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.shared.ldap.cursor;
020    
021    
022    import java.util.Comparator;
023    
024    import org.apache.directory.shared.i18n.I18n;
025    
026    
027    /**
028     * A Cursor over a single element.
029     *
030     * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
031     * @version $Rev$, $Date$
032     */
033    public class SingletonCursor<E> extends AbstractCursor<E>
034    {
035        /** A flag set to true to a*/
036        private boolean beforeFirst = true;
037        private boolean afterLast;
038        private boolean onSingleton;
039        
040        /** The comparator used for this cursor. */
041        private final Comparator<E> comparator;
042        
043        /** The unique element stored in the cursor */
044        private final E singleton;
045    
046    
047        /**
048         * Creates a new instance of SingletonCursor.
049         *
050         * @param singleton The unique element to store into this cursor
051         */
052        public SingletonCursor( E singleton )
053        {
054            this( singleton, null );
055        }
056    
057    
058        /**
059         * Creates a new instance of SingletonCursor, with its associated
060         * conmparator
061         *
062         * @param singleton The unique element to store into this cursor
063         * @param comparator The associated comparator
064         */
065        public SingletonCursor( E singleton, Comparator<E> comparator )
066        {
067            this.singleton = singleton;
068            this.comparator = comparator;
069        }
070    
071    
072        /**
073         * {@inheritDoc}
074         */
075        public boolean available()
076        {
077            return onSingleton;
078        }
079        
080    
081        /**
082         * {@inheritDoc}
083         */
084        public void before( E element ) throws Exception
085        {
086            checkNotClosed( "before()" );
087    
088            if ( comparator == null )
089            {
090                throw new UnsupportedOperationException( I18n.err( I18n.ERR_02010 ) );
091            }
092    
093            int comparison = comparator.compare( singleton, element );
094    
095            if ( comparison < 0 )
096            {
097                first();
098            }
099            else
100            {
101                beforeFirst();
102            }
103        }
104    
105    
106        /**
107         * {@inheritDoc}
108         */
109        public void after( E element ) throws Exception
110        {
111            checkNotClosed( "after()" );
112    
113            if ( comparator == null )
114            {
115                throw new UnsupportedOperationException( I18n.err( I18n.ERR_02011 ) );
116            }
117    
118            int comparison = comparator.compare( singleton, element );
119    
120            if ( comparison > 0 )
121            {
122                first();
123            }
124            else
125            {
126                afterLast();
127            }
128        }
129    
130    
131        /**
132         * {@inheritDoc}
133         */
134        public void beforeFirst() throws Exception
135        {
136            checkNotClosed( "()" );
137            beforeFirst = true;
138            afterLast = false;
139            onSingleton = false;
140        }
141    
142    
143        /**
144         * {@inheritDoc}
145         */
146        public void afterLast() throws Exception
147        {
148            checkNotClosed( "()" );
149            beforeFirst = false;
150            afterLast = true;
151            onSingleton = false;
152        }
153    
154    
155        /**
156         * {@inheritDoc}
157         */
158        public boolean first() throws Exception
159        {
160            checkNotClosed( "()" );
161            beforeFirst = false;
162            onSingleton = true;
163            afterLast = false;
164            return true;
165        }
166    
167    
168        /**
169         * {@inheritDoc}
170         */
171        public boolean last() throws Exception
172        {
173            checkNotClosed( "()" );
174            beforeFirst = false;
175            onSingleton = true;
176            afterLast = false;
177            return true;
178        }
179    
180    
181        /**
182         * {@inheritDoc}
183         */
184        public boolean isFirst() throws Exception
185        {
186            checkNotClosed( "()" );
187            return onSingleton;
188        }
189    
190    
191        /**
192         * {@inheritDoc}
193         */
194        public boolean isLast() throws Exception
195        {
196            checkNotClosed( "()" );
197            return onSingleton;
198        }
199    
200    
201        /**
202         * {@inheritDoc}
203         */
204        public boolean isAfterLast() throws Exception
205        {
206            checkNotClosed( "()" );
207            return afterLast;
208        }
209    
210    
211        /**
212         * {@inheritDoc}
213         */
214        public boolean isBeforeFirst() throws Exception
215        {
216            checkNotClosed( "()" );
217            return beforeFirst;
218        }
219    
220    
221        /**
222         * {@inheritDoc}
223         */
224        public boolean previous() throws Exception
225        {
226            checkNotClosed( "()" );
227            
228            if ( beforeFirst )
229            {
230                return false;
231            }
232    
233            if ( afterLast )
234            {
235                beforeFirst = false;
236                onSingleton = true;
237                afterLast = false;
238                return true;
239            }
240    
241            // must be on the singleton
242            beforeFirst = true;
243            onSingleton = false;
244            afterLast = false;
245            return false;
246        }
247    
248    
249        /**
250         * {@inheritDoc}
251         */
252        public boolean next() throws Exception
253        {
254            checkNotClosed( "()" );
255            
256            if ( beforeFirst )
257            {
258                beforeFirst = false;
259                onSingleton = true;
260                afterLast = false;
261                return true;
262            }
263    
264            if ( afterLast )
265            {
266                return false;
267            }
268    
269            // must be on the singleton
270            beforeFirst = false;
271            onSingleton = false;
272            afterLast = true;
273            return false;
274        }
275    
276    
277        /**
278         * {@inheritDoc}
279         */
280        public E get() throws Exception
281        {
282            checkNotClosed( "()" );
283            
284            if ( onSingleton )
285            {
286                return singleton;
287            }
288    
289            if ( beforeFirst )
290            {
291                throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02012 ) );
292            }
293            else
294            {
295                throw new InvalidCursorPositionException( I18n.err( I18n.ERR_02013 ) );
296            }
297        }
298    
299    
300        /**
301         * {@inheritDoc}
302         */
303        public boolean isElementReused()
304        {
305            return true;
306        }
307    }