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     * @author Martin Krasser
028     * 
029     * @version $Revision: 52060 $
030     */
031    public class Sequence<E> extends TreeSet<E> {
032    
033        private static final long serialVersionUID = 5647393631147741711L;
034    
035        private SequenceElementComparator<E> comparator;
036        
037        /**
038         * Creates a new {@link Sequence} instance.
039         * 
040         * @param comparator a strategy for comparing elements of this sequence.
041         */
042        public Sequence(SequenceElementComparator<E> comparator) {
043            super(comparator);
044            this.comparator = comparator;
045        }
046        
047        /**
048         * Returns the immediate predecessor of the given element in this sequence
049         * or <code>null</code> if no predecessor exists.
050         * 
051         * @param e an element which is compared to elements of this sequence.
052         * @return an element of this sequence or <code>null</code>.
053         */
054        public E predecessor(E e) {
055            E elem = lower(e);
056            if (elem == null) {
057                return null;
058            }
059            if (comparator.predecessor(elem, e)) {
060                return elem;
061            }
062            return null;
063        }
064        
065        /**
066         * Returns the immediate successor of the given element in this sequence
067         * or <code>null</code> if no successor exists.
068         * 
069         * @param e an element which is compared to elements of this sequence.
070         * @return an element of this sequence or <code>null</code>.
071         */
072        public E successor(E e) {
073            E elem = higher(e);
074            if (elem == null) {
075                return null;
076            }
077            if (comparator.successor(elem, e)) {
078                return elem;
079            }
080            return null;
081        }
082        
083        /**
084         * Returns this sequence's comparator.
085         * 
086         * @return this sequence's comparator.
087         */
088        public SequenceElementComparator<E> comparator() {
089            return comparator;
090        }
091    
092        /**
093         * Returns the next higher element in the sequence to the given element. If
094         * the given element doesn't exist or if it is the last element in the
095         * sequence <code>null</code> is returned. <strong>Please note that this
096         * method is provided for compatibility with Java 5 SE. On a Java 6 SE
097         * platform the same method implemented by the {@link TreeSet}
098         * class should be used for better performance.</strong>
099         * 
100         * @param e an element which is compared to elements of this sequence.
101         * @return an element of this sequence or <code>null</code>.
102         */
103        public E higher(E e) {
104            boolean found = false;
105            for (E current : this) {
106                if (found) {
107                    return current;
108                }
109                if (comparator.compare(e, current) == 0) {
110                    found = true;
111                }
112            }
113            return null;
114        }
115    
116        /**
117         * Returns the next lower element in the sequence to the given element. If
118         * the given element doesn't exist or if it is the first element in the
119         * sequence <code>null</code> is returned. <strong>Please note that this
120         * method is provided for compatibility with Java 5 SE. On a Java 6 SE
121         * platform the same method implemented by the {@link TreeSet}
122         * class should be used for better performance.</strong>
123         * 
124         * @param e an element which is compared to elements of this sequence.
125         * @return an element of this sequence or <code>null</code>.
126         */
127        public E lower(E e) {
128            E last = null;
129            for (E current : this) {
130                if (comparator.compare(e, current) == 0) {
131                    return last;
132                }
133                last = current;
134            }
135            return last;
136        }
137        
138    }