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.xdbm.search.impl; 021 022 023 import org.apache.directory.server.xdbm.IndexEntry; 024 import org.apache.directory.server.xdbm.Store; 025 import org.apache.directory.server.xdbm.AbstractIndexCursor; 026 import org.apache.directory.server.xdbm.IndexCursor; 027 import org.apache.directory.server.xdbm.search.Evaluator; 028 import org.apache.directory.server.i18n.I18n; 029 import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException; 030 import org.apache.directory.shared.ldap.entry.ServerEntry; 031 import org.apache.directory.shared.ldap.filter.ExprNode; 032 033 034 /** 035 * A Cursor returning candidates satisfying a logical negation expression. 036 * 037 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 038 * @version $$Rev$$ 039 */ 040 public class NotCursor<V, ID> extends AbstractIndexCursor<V, ServerEntry, ID> 041 { 042 private static final String UNSUPPORTED_MSG = I18n.err( I18n.ERR_718 ); 043 private final IndexCursor<V, ServerEntry, ID> ndnCursor; 044 private final Evaluator<? extends ExprNode, ServerEntry, ID> childEvaluator; 045 private boolean available = false; 046 047 048 @SuppressWarnings("unchecked") 049 public NotCursor( Store<ServerEntry, ID> db, Evaluator<? extends ExprNode, ServerEntry, ID> childEvaluator ) 050 throws Exception 051 { 052 this.childEvaluator = childEvaluator; 053 this.ndnCursor = ( IndexCursor<V, ServerEntry, ID> ) db.getNdnIndex().forwardCursor(); 054 } 055 056 057 public boolean available() 058 { 059 return available; 060 } 061 062 063 public void beforeValue( ID id, V value ) throws Exception 064 { 065 throw new UnsupportedOperationException( UNSUPPORTED_MSG ); 066 } 067 068 069 public void before( IndexEntry<V, ServerEntry, ID> element ) throws Exception 070 { 071 throw new UnsupportedOperationException( UNSUPPORTED_MSG ); 072 } 073 074 075 public void after( IndexEntry<V, ServerEntry, ID> element ) throws Exception 076 { 077 throw new UnsupportedOperationException( UNSUPPORTED_MSG ); 078 } 079 080 081 public void afterValue( ID id, V value ) throws Exception 082 { 083 throw new UnsupportedOperationException( UNSUPPORTED_MSG ); 084 } 085 086 087 public void beforeFirst() throws Exception 088 { 089 checkNotClosed( "beforeFirst()" ); 090 ndnCursor.beforeFirst(); 091 available = false; 092 } 093 094 095 public void afterLast() throws Exception 096 { 097 checkNotClosed( "afterLast()" ); 098 ndnCursor.afterLast(); 099 available = false; 100 } 101 102 103 public boolean first() throws Exception 104 { 105 beforeFirst(); 106 return next(); 107 } 108 109 110 public boolean last() throws Exception 111 { 112 afterLast(); 113 return previous(); 114 } 115 116 117 public boolean previous() throws Exception 118 { 119 while ( ndnCursor.previous() ) 120 { 121 checkNotClosed( "previous()" ); 122 IndexEntry<?, ServerEntry, ID> candidate = ndnCursor.get(); 123 if ( !childEvaluator.evaluate( candidate ) ) 124 { 125 return available = true; 126 } 127 } 128 129 return available = false; 130 } 131 132 133 public boolean next() throws Exception 134 { 135 while ( ndnCursor.next() ) 136 { 137 checkNotClosed( "next()" ); 138 IndexEntry<?, ServerEntry, ID> candidate = ndnCursor.get(); 139 if ( !childEvaluator.evaluate( candidate ) ) 140 { 141 return available = true; 142 } 143 } 144 145 return available = false; 146 } 147 148 149 public IndexEntry<V, ServerEntry, ID> get() throws Exception 150 { 151 checkNotClosed( "get()" ); 152 if ( available ) 153 { 154 return ndnCursor.get(); 155 } 156 157 throw new InvalidCursorPositionException( I18n.err( I18n.ERR_708 ) ); 158 } 159 160 161 public boolean isElementReused() 162 { 163 return ndnCursor.isElementReused(); 164 } 165 166 167 public void close() throws Exception 168 { 169 super.close(); 170 ndnCursor.close(); 171 } 172 }