/* * Copyright 2003-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.codehaus.groovy.util; import java.util.ArrayList; import java.util.Iterator; import java.util.List; /** * This class provides a very simple linked list of memory managed elements. * This class does not support concurrent modifications nor will it check * for them. This class is also not thread safe. * * @author Jochen Theodorou * @since 1.6 */ public class ManagedLinkedList<T> { private final class Element<V> extends ManagedReference<V> { Element next; Element previous; public Element(ReferenceBundle bundle, V value) { super(bundle, value); } public void finalizeReference() { if (previous != null && previous.next != null) { previous.next = next; } if (next != null && next.previous != null) { next.previous = previous; } if (this == head) head = next; next = null; if (this == tail) tail = previous; previous = null; super.finalizeReference(); } } private final class Iter implements Iterator<T> { private Element<T> current; private boolean currentHandled = false; Iter() { current = head; } public boolean hasNext() { if (current == null) return false; if (currentHandled) { return current.next != null; } else { return current != null; } } public T next() { if (currentHandled) current = current.next; currentHandled = true; if (current == null) return null; return current.get(); } public void remove() { if (current != null) current.finalizeReference(); } } private Element<T> tail; private Element<T> head; private ReferenceBundle bundle; public ManagedLinkedList(ReferenceBundle bundle) { this.bundle = bundle; } /** * adds a value to the list * * @param value the value */ public void add(T value) { Element<T> element = new Element<T>(bundle, value); element.previous = tail; if (tail != null) tail.next = element; tail = element; if (head == null) head = element; } /** * returns an iterator, which allows the removal of elements. * The next() method of the iterator may return null values. This * is especially the case if the value was removed. * * @return the Iterator */ public Iterator<T> iterator() { return new Iter(); } /** * Returns an array of non null elements from the source array. * * @param tArray the source array * @return the array */ public T[] toArray(T[] tArray) { List<T> array = new ArrayList<T>(100); for (Iterator<T> it = iterator(); it.hasNext();) { T val = it.next(); if (val != null) array.add(val); } return array.toArray(tArray); } /** * returns if the list is empty * * @return true if the list is empty */ public boolean isEmpty() { return head == null; } }