001    /**
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements.  See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache License, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License.  You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the License for the specific language governing permissions and
015     * limitations under the License.
016     */
017    package org.apache.camel.processor.resequencer;
018    
019    import java.util.TreeSet;
020    
021    /**
022     * A sorted set of elements with additional methods for obtaining immediate
023     * successors and immediate predecessors of a given element in the sequence.
024     * Successors and predecessors are calculated by using a
025     * {@link SequenceElementComparator}.
026     * 
027     * @version 
028     */
029    public class Sequence<E> extends TreeSet<E> {
030    
031        private static final long serialVersionUID = 5647393631147741711L;
032    
033        private SequenceElementComparator<E> comparator;
034        
035        /**
036         * Creates a new {@link Sequence} instance.
037         * 
038         * @param comparator a strategy for comparing elements of this sequence.
039         */
040        public Sequence(SequenceElementComparator<E> comparator) {
041            super(comparator);
042            this.comparator = comparator;
043        }
044        
045        /**
046         * Returns the immediate predecessor of the given element in this sequence
047         * or <code>null</code> if no predecessor exists.
048         * 
049         * @param e an element which is compared to elements of this sequence.
050         * @return an element of this sequence or <code>null</code>.
051         */
052        public E predecessor(E e) {
053            E elem = lower(e);
054            if (elem == null) {
055                return null;
056            }
057            if (comparator.predecessor(elem, e)) {
058                return elem;
059            }
060            return null;
061        }
062        
063        /**
064         * Returns the immediate successor of the given element in this sequence
065         * or <code>null</code> if no successor exists.
066         * 
067         * @param e an element which is compared to elements of this sequence.
068         * @return an element of this sequence or <code>null</code>.
069         */
070        public E successor(E e) {
071            E elem = higher(e);
072            if (elem == null) {
073                return null;
074            }
075            if (comparator.successor(elem, e)) {
076                return elem;
077            }
078            return null;
079        }
080        
081        /**
082         * Returns this sequence's comparator.
083         * 
084         * @return this sequence's comparator.
085         */
086        public SequenceElementComparator<E> comparator() {
087            return comparator;
088        }
089    
090        /**
091         * Returns the next higher element in the sequence to the given element. If
092         * the given element doesn't exist or if it is the last element in the
093         * sequence <code>null</code> is returned. <strong>Please note that this
094         * method is provided for compatibility with Java 5 SE. On a Java 6 SE
095         * platform the same method implemented by the {@link TreeSet}
096         * class should be used for better performance.</strong>
097         * 
098         * @param e an element which is compared to elements of this sequence.
099         * @return an element of this sequence or <code>null</code>.
100         */
101        public E higher(E e) {
102            boolean found = false;
103            for (E current : this) {
104                if (found) {
105                    return current;
106                }
107                if (comparator.compare(e, current) == 0) {
108                    found = true;
109                }
110            }
111            return null;
112        }
113    
114        /**
115         * Returns the next lower element in the sequence to the given element. If
116         * the given element doesn't exist or if it is the first element in the
117         * sequence <code>null</code> is returned. <strong>Please note that this
118         * method is provided for compatibility with Java 5 SE. On a Java 6 SE
119         * platform the same method implemented by the {@link TreeSet}
120         * class should be used for better performance.</strong>
121         * 
122         * @param e an element which is compared to elements of this sequence.
123         * @return an element of this sequence or <code>null</code>.
124         */
125        public E lower(E e) {
126            E last = null;
127            for (E current : this) {
128                if (comparator.compare(e, current) == 0) {
129                    return last;
130                }
131                last = current;
132            }
133            return last;
134        }
135        
136    }