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.avltree; 021 022 023import java.io.IOException; 024 025import org.apache.directory.api.ldap.model.constants.Loggers; 026import org.apache.directory.api.ldap.model.cursor.AbstractCursor; 027import org.apache.directory.api.ldap.model.cursor.CursorException; 028import org.apache.directory.api.ldap.model.cursor.InvalidCursorPositionException; 029import org.apache.directory.api.ldap.model.cursor.Tuple; 030import org.apache.directory.api.ldap.model.exception.LdapException; 031import org.slf4j.Logger; 032import org.slf4j.LoggerFactory; 033 034 035/** 036 * A cursor that converts SingletonOrOrderedSet objects in the value from a 037 * AvlTreeMap into Tuples with just K and V presuming that all the keys have 038 * no duplicates. 039 * 040 * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a> 041 */ 042public class AvlTreeMapNoDupsWrapperCursor<K, V> extends AbstractCursor<Tuple<K, V>> 043{ 044 /** A dedicated log for cursors */ 045 private static final Logger LOG_CURSOR = LoggerFactory.getLogger( Loggers.CURSOR_LOG.getName() ); 046 047 /** Speedup for logs */ 048 private static final boolean IS_DEBUG = LOG_CURSOR.isDebugEnabled(); 049 050 private final AvlSingletonOrOrderedSetCursor<K, V> wrapped; 051 private final Tuple<K, V> returnedTuple = new Tuple<>(); 052 053 054 public AvlTreeMapNoDupsWrapperCursor( AvlSingletonOrOrderedSetCursor<K, V> wrapped ) 055 { 056 if ( IS_DEBUG ) 057 { 058 LOG_CURSOR.debug( "Creating AvlTreeMapNoDupsWrapperCursor {}", this ); 059 } 060 061 this.wrapped = wrapped; 062 } 063 064 065 public void afterKey( K key ) throws Exception 066 { 067 wrapped.afterKey( key ); 068 } 069 070 071 public void afterValue( K key, V value ) throws Exception 072 { 073 throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." ); 074 } 075 076 077 public void beforeKey( K key ) throws Exception 078 { 079 wrapped.beforeKey( key ); 080 } 081 082 083 public void beforeValue( K key, V value ) throws Exception 084 { 085 throw new UnsupportedOperationException( "This Cursor does not support duplicate keys." ); 086 } 087 088 089 /** 090 * {@inheritDoc} 091 */ 092 public void after( Tuple<K, V> element ) throws LdapException, CursorException 093 { 094 wrapped.afterKey( element.getKey() ); 095 } 096 097 098 /** 099 * {@inheritDoc} 100 */ 101 public void afterLast() throws LdapException, CursorException 102 { 103 wrapped.afterLast(); 104 } 105 106 107 /** 108 * {@inheritDoc} 109 */ 110 public boolean available() 111 { 112 return wrapped.available(); 113 } 114 115 116 /** 117 * {@inheritDoc} 118 */ 119 public void before( Tuple<K, V> element ) throws LdapException, CursorException 120 { 121 wrapped.beforeKey( element.getKey() ); 122 } 123 124 125 /** 126 * {@inheritDoc} 127 */ 128 public void beforeFirst() throws LdapException, CursorException 129 { 130 wrapped.beforeFirst(); 131 } 132 133 134 /** 135 * {@inheritDoc} 136 */ 137 public boolean first() throws LdapException, CursorException 138 { 139 return wrapped.first(); 140 } 141 142 143 /** 144 * {@inheritDoc} 145 */ 146 public Tuple<K, V> get() throws CursorException 147 { 148 if ( wrapped.available() ) 149 { 150 Tuple<K, SingletonOrOrderedSet<V>> tuple = wrapped.get(); 151 152 if ( tuple.getValue().isOrderedSet() ) 153 { 154 tuple.getValue().getOrderedSet().printTree(); 155 } 156 157 returnedTuple.setBoth( tuple.getKey(), tuple.getValue().getSingleton() ); 158 return returnedTuple; 159 } 160 161 throw new InvalidCursorPositionException(); 162 } 163 164 165 /** 166 * {@inheritDoc} 167 */ 168 public boolean last() throws LdapException, CursorException 169 { 170 return wrapped.last(); 171 } 172 173 174 /** 175 * {@inheritDoc} 176 */ 177 public boolean next() throws LdapException, CursorException 178 { 179 return wrapped.next(); 180 } 181 182 183 /** 184 * {@inheritDoc} 185 */ 186 public boolean previous() throws LdapException, CursorException 187 { 188 return wrapped.previous(); 189 } 190 191 192 /** 193 * {@inheritDoc} 194 */ 195 @Override 196 public void close() throws IOException 197 { 198 if ( IS_DEBUG ) 199 { 200 LOG_CURSOR.debug( "Closing AvlTreeMapNoDupsWrapperCursor {}", this ); 201 } 202 203 wrapped.close(); 204 } 205 206 207 /** 208 * {@inheritDoc} 209 */ 210 @Override 211 public void close( Exception reason ) throws IOException 212 { 213 if ( IS_DEBUG ) 214 { 215 LOG_CURSOR.debug( "Closing AvlTreeMapNoDupsWrapperCursor {}", this ); 216 } 217 218 wrapped.close( reason ); 219 } 220}