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}