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: 697732 $
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 }