/* ******************************************************************************
* Copyright (c) 2006-2012 XMind Ltd. and others.
*
* This file is a part of XMind 3. XMind releases 3 and
* above are dual-licensed under the Eclipse Public License (EPL),
* which is available at http://www.eclipse.org/legal/epl-v10.html
* and the GNU Lesser General Public License (LGPL),
* which is available at http://www.gnu.org/licenses/lgpl.html
* See http://www.xmind.net/license.html for details.
*
* Contributors:
* XMind Ltd. - initial API and implementation
*******************************************************************************/
package org.xmind.ui.util;
import java.util.Iterator;
public class Chainability {
private Chainability() {
throw new AssertionError();
}
/**
* Inserts an element into the chain after the specified one.
* <p>
* Example:
* </p>
* <p>
* Inserting B after A <blockquote>... - ''A - 'A - A - A' - A'' -
* ...</blockquote> results <blockquote>... - ''A - 'A - A - B - A' - A'' -
* ...</blockquote>
* </p>
*
* @param chained
* an element in the chain
* @param element
* the element to be inserted into the chain
*/
public static <T extends IChained<T>> void insertAfter(T chained, T element) {
T next = chained.getNext();
if (next != null) {
next.setPrevious(element);
}
chained.setNext(element);
element.setNext(next);
element.setPrevious(chained);
}
/**
* Joins two sub-chains. The new chain consists of the <code>left</code>
* element and all its previous elements plus the <code>right</code> element
* and all its next elements.
*
* <p>
* Example:
* </p>
* <p>
* Concatenate A <blockquote>... - ''A - 'A - A - A' - A'' -
* ...</blockquote> and B <blockquote>... - ''B - 'B - B - B' - B'' -
* ...</blockquote> results <blockquote>... - ''A - 'A - A - B - B' - B'' -
* ...</blockquote>
*
* @param left
* an element at the end of the left sub-chain
* @param right
* an element at the beginning of the right sub-chain
*/
public static <T extends IChained<T>> void concatenate(T left, T right) {
T next = left.getNext();
if (next != null) {
next.setPrevious(null);
}
T previous = right.getPrevious();
if (previous != null) {
previous.setNext(null);
}
left.setNext(right);
right.setPrevious(left);
}
/**
* Removes an element from its chain.
*
* @param element
* an element in the chain
*/
public static <T extends IChained<T>> void remove(T element) {
T previous = element.getPrevious();
T next = element.getNext();
if (previous != null) {
previous.setNext(next);
}
if (next != null) {
next.setPrevious(previous);
}
element.setPrevious(null);
element.setNext(null);
}
/**
* Constructs an iterator that iterates over the chain from the specified
* starting element to the specified ending element (both included).
*
* @param start
* an element in the chain
* @param end
* another element in the chain
* @return an {@link Iterator} object
*/
public static <T extends IChained<T>> Iterator<T> iterate(final T start,
final T end) {
return new Iterator<T>() {
T next = start;
public boolean hasNext() {
return next != null;
}
public T next() {
T n = next;
next = (next == null || next == end) ? null : next.getNext();
return n;
}
public void remove() {
// do nothing
}
};
}
}