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 */
017package org.apache.camel.processor.resequencer;
018
019import 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 */
029public 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}