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.core.partition.impl.btree; 021 022 023import java.util.NoSuchElementException; 024import java.util.regex.Pattern; 025 026import javax.naming.NamingEnumeration; 027import javax.naming.NamingException; 028 029import org.apache.directory.api.ldap.model.cursor.Tuple; 030import org.apache.directory.api.util.exception.NotImplementedException; 031import org.apache.directory.server.xdbm.IndexEntry; 032 033 034/** 035 * A NamingEnumeration over an Index which returns IndexRecords. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 */ 039public class IndexEnumeration<T> implements NamingEnumeration<IndexEntry> 040{ 041 /** */ 042 private final Pattern re; 043 /** */ 044 private final IndexEntry tmp = new IndexEntry(); 045 /** */ 046 private final IndexEntry returned = new IndexEntry(); 047 /** */ 048 private final IndexEntry prefetched = new IndexEntry(); 049 /** */ 050 private final boolean swapKeyVal; 051 /** */ 052 private final NamingEnumeration<Tuple> underlying; 053 054 /** */ 055 private boolean hasMore = true; 056 057 058 // ------------------------------------------------------------------------ 059 // C O N S T R U C T O R S 060 // ------------------------------------------------------------------------ 061 062 public IndexEnumeration( NamingEnumeration<Tuple> list ) throws NamingException 063 { 064 this( list, false, null ); 065 } 066 067 068 public IndexEnumeration( NamingEnumeration<Tuple> list, boolean swapKeyVal ) throws NamingException 069 { 070 this( list, swapKeyVal, null ); 071 } 072 073 074 public IndexEnumeration( NamingEnumeration<Tuple> list, boolean swapKeyVal, Pattern regex ) throws NamingException 075 { 076 re = regex; 077 underlying = list; 078 this.swapKeyVal = swapKeyVal; 079 080 if ( !underlying.hasMore() ) 081 { 082 hasMore = false; 083 return; 084 } 085 086 prefetch(); 087 } 088 089 090 // ------------------------------------------------------------------------ 091 // NamingEnumeration Interface Methods 092 // ------------------------------------------------------------------------ 093 094 /** 095 * @see javax.naming.NamingEnumeration#next() 096 */ 097 public IndexEntry next() throws NamingException 098 { 099 returned.copy( prefetched ); 100 prefetch(); 101 return returned; 102 } 103 104 105 /** 106 * @see java.util.Enumeration#nextElement() 107 */ 108 public IndexEntry nextElement() 109 { 110 try 111 { 112 return next(); 113 } 114 catch ( NamingException ne ) 115 { 116 throw new NoSuchElementException(); 117 } 118 } 119 120 121 /** 122 * @see javax.naming.NamingEnumeration#hasMore() 123 */ 124 public boolean hasMore() 125 { 126 return hasMore; 127 } 128 129 130 /** 131 * @see javax.naming.NamingEnumeration#hasMoreElements() 132 */ 133 public boolean hasMoreElements() 134 { 135 return hasMore; 136 } 137 138 139 /** 140 * @see javax.naming.NamingEnumeration#close() 141 */ 142 public void close() throws NamingException 143 { 144 hasMore = false; 145 underlying.close(); 146 } 147 148 149 // ------------------------------------------------------------------------ 150 // Private Methods 151 // ------------------------------------------------------------------------ 152 153 private void prefetch() throws NamingException 154 { 155 while ( underlying.hasMore() ) 156 { 157 Tuple tuple = underlying.next(); 158 159 if ( swapKeyVal ) 160 { 161 throw new NotImplementedException(); 162 // tmp.setSwapped( tuple, null ); 163 } 164 else 165 { 166 tmp.setTuple( tuple ); 167 } 168 169 // If regex is null just transfer into prefetched from tmp record 170 // but if it is not then use it to match. Successful match shorts 171 // while loop. 172 if ( null == re || re.matcher( ( String ) tmp.getKey() ).matches() ) 173 { 174 prefetched.copy( tmp ); 175 return; 176 } 177 } 178 179 // If we got down here then cursor has been consumed without a match! 180 hasMore = false; 181 } 182}