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