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 }