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    package org.apache.directory.server.xdbm;
020    
021    
022    import org.apache.directory.server.i18n.I18n;
023    import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
024    
025    
026    /**
027     * A Cursor over a single element.
028     *
029     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
030     * @version $Rev$, $Date$
031     */
032    public class SingletonIndexCursor<K, E, ID> extends AbstractIndexCursor<K, E, ID>
033    {
034        private boolean beforeFirst = true;
035        private boolean afterLast;
036        private boolean onSingleton;
037        private final IndexEntry<K, E, ID> singleton;
038    
039    
040        public SingletonIndexCursor( IndexEntry<K, E, ID> singleton )
041        {
042            this.singleton = singleton;
043        }
044    
045    
046        public boolean available()
047        {
048            return onSingleton;
049        }
050    
051    
052        public void before( IndexEntry<K, E, ID> element ) throws Exception
053        {
054            throw new UnsupportedOperationException();
055        }
056    
057    
058        public void beforeValue( ID id, K value ) throws Exception
059        {
060            throw new UnsupportedOperationException();
061        }
062    
063    
064        public void afterValue( ID id, K value ) throws Exception
065        {
066            throw new UnsupportedOperationException();
067        }
068    
069    
070        public void after( IndexEntry<K, E, ID> element ) throws Exception
071        {
072            throw new UnsupportedOperationException();
073        }
074    
075    
076        public void beforeFirst() throws Exception
077        {
078            checkNotClosed( "()" );
079            beforeFirst = true;
080            afterLast = false;
081            onSingleton = false;
082        }
083    
084    
085        public void afterLast() throws Exception
086        {
087            checkNotClosed( "()" );
088            beforeFirst = false;
089            afterLast = true;
090            onSingleton = false;
091        }
092    
093    
094        public boolean first() throws Exception
095        {
096            checkNotClosed( "()" );
097            beforeFirst = false;
098            onSingleton = true;
099            afterLast = false;
100            return true;
101        }
102    
103    
104        public boolean last() throws Exception
105        {
106            checkNotClosed( "()" );
107            beforeFirst = false;
108            onSingleton = true;
109            afterLast = false;
110            return true;
111        }
112    
113    
114        public boolean isFirst() throws Exception
115        {
116            checkNotClosed( "()" );
117            return onSingleton;
118        }
119    
120    
121        public boolean isLast() throws Exception
122        {
123            checkNotClosed( "()" );
124            return onSingleton;
125        }
126    
127    
128        public boolean isAfterLast() throws Exception
129        {
130            checkNotClosed( "()" );
131            return afterLast;
132        }
133    
134    
135        public boolean isBeforeFirst() throws Exception
136        {
137            checkNotClosed( "()" );
138            return beforeFirst;
139        }
140    
141    
142        public boolean previous() throws Exception
143        {
144            checkNotClosed( "()" );
145            if ( beforeFirst )
146            {
147                return false;
148            }
149    
150            if ( afterLast )
151            {
152                beforeFirst = false;
153                onSingleton = true;
154                afterLast = false;
155                return true;
156            }
157    
158            // must be on the singleton
159            beforeFirst = true;
160            onSingleton = false;
161            afterLast = false;
162            return false;
163        }
164    
165    
166        public boolean next() throws Exception
167        {
168            checkNotClosed( "()" );
169            if ( beforeFirst )
170            {
171                beforeFirst = false;
172                onSingleton = true;
173                afterLast = false;
174                return true;
175            }
176    
177            if ( afterLast )
178            {
179                return false;
180            }
181    
182            // must be on the singleton
183            beforeFirst = false;
184            onSingleton = false;
185            afterLast = true;
186            return false;
187        }
188    
189    
190        public IndexEntry<K, E, ID> get() throws Exception
191        {
192            checkNotClosed( "()" );
193            if ( onSingleton )
194            {
195                return singleton;
196            }
197    
198            if ( beforeFirst )
199            {
200                throw new InvalidCursorPositionException( I18n.err( I18n.ERR_705 ) );
201            }
202            else
203            {
204                throw new InvalidCursorPositionException( I18n.err( I18n.ERR_706 ) );
205            }
206        }
207    
208    
209        public boolean isElementReused()
210        {
211            return true;
212        }
213    }