/**
* Copyright 2011-2017 Asakusa Framework Team.
*
* 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 com.asakusafw.runtime.flow;
import java.util.List;
/**
* A List interface for reusing instances of element objects.
<pre><code>
Iterator<Hoge> iter = ...;
ListBuffer<Hoge> hoges = ...;
...
hoges.begin();
while (iter.hasNext()) {
Hoge hoge = iter.next();
if (hoges.isExpandRequired()) {
hoges.expand(new Hoge());
}
hoges.advance().set(hoge);
}
hoges.end();
// use hoges as List
hoges.shrink();
</code></pre>
* @param <E> the element type
*/
public interface ListBuffer<E> extends List<E> {
/**
* Begins changing the list buffer.
* Initially, the internal cursor is on the head of this buffer, and clients can move it to the next element
* by invoking {@link #advance()}.
* After changing the buffer, then clients must invoke {@link #end()} and the buffer can be used as the
* unmodifiable list.
* @see #advance()
* @throws BufferException if failed to prepare buffer
*/
void begin();
/**
* Ends changing the list buffer.
* After this, clients should not change the buffer contents.
* If clients want to change the buffer, must invoke {@link #begin()} once more.
* @throws BufferException if failed to prepare buffer
*/
void end();
/**
* Returns whether a new element object is required for the buffer or not.
* If it required, clients must use {@link #expand(Object)} to add a new object before invoke {@link #advance()}.
* This method must be invoked between {@link #begin()} and {@link #end()}.
* @return {@code true} if a new element object is required, otherwise {@code false}
* @see #expand(Object)
* @throws BufferException if failed to prepare buffer
*/
boolean isExpandRequired();
/**
* Adds a new element object into the tail of this buffer.
* This method must be invoked between {@link #begin()} and {@link #end()}.
* @param value the object
* @see #isExpandRequired()
* @throws IndexOutOfBoundsException if expand is not required (optional operation)
* @see #isExpandRequired()
* @throws BufferException if failed to prepare buffer
*/
void expand(E value);
/**
* Returns the next element object on the internal cursor, and then move the cursor to the next element.
* This method must be invoked between {@link #begin()} and {@link #end()}.
* @return the next element object
* @throws IndexOutOfBoundsException if the next element object is not prepared
* @see #isExpandRequired()
* @see #expand(Object)
* @throws BufferException if failed to prepare buffer
*/
E advance();
/**
* Shrinks this buffer.
*/
void shrink();
}