2 * fcplib - HighLevelCallback.java -
3 * Copyright © 2008 David Roden
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 package net.pterodactylus.fcp.highlevel;
22 import java.util.ArrayList;
23 import java.util.Collections;
24 import java.util.List;
27 * A callback is used to notify users of the {@link HighLevelClient} that an
28 * operation was completed.
31 * The type of the high-level operation result
32 * @author David ‘Bombe’ Roden <bombe@freenetproject.org>
35 public class HighLevelCallback<R extends HighLevelResult> {
37 /** Object used for synchronization. */
38 protected final Object syncObject = new Object();
40 /** The list of callback listeners. */
41 private final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
43 /** Whether the result is complete. */
44 protected boolean resultComplete = false;
46 /** The result of the operation. */
47 private R result = null;
50 * Package-private construtor.
53 * The result of the operation
55 HighLevelCallback(R result) {
60 * Adds a callback listener to this callback. The callback listener will be
61 * called as soon as the result of the operation is known. If the result is
62 * already known, the listener will be called immediately. Also, as soon as
63 * a listener was notified the listener is automatically removed from this
66 * @param highLevelCallbackListener
69 public void addHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
70 highLevelCallbackListeners.add(highLevelCallbackListener);
77 * Removes a callback listener from this callback.
79 * @param highLevelCallbackListener
80 * The listener to remove
82 public void removeHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
83 highLevelCallbackListeners.remove(highLevelCallbackListener);
87 * Notifies all listeners that the result of the operation is now known. As
88 * soon as a listener was notified it will be removed from the list of
91 * @see HighLevelCallbackListener#gotResult(HighLevelCallback)
93 private synchronized void fireGotResult() {
94 for (HighLevelCallbackListener<R> highLevelCallbackListener: highLevelCallbackListeners) {
95 highLevelCallbackListener.gotResult(this);
97 highLevelCallbackListeners.clear();
101 * Returns whether the result of the operation is already known. If the
102 * result is already known a call to {@link #getResult()} will not block.
104 * @return <code>true</code> if the result is already known,
105 * <code>false</code> otherwise
107 public boolean isDone() {
108 synchronized (syncObject) {
109 return resultComplete;
114 * Returns the result of the operation, blocking until it is known.
116 * @return The result of the operation
117 * @throws InterruptedException
118 * if {@link Object#wait()} was interrupted
120 public R getResult() throws InterruptedException {
125 * Returns the result of the operation, blocking until it is known or the
126 * given time (in milliseconds) has passed.
129 * The time to wait for a result
130 * @return The result of the operation, or <code>null</code> if the result
131 * is still not known after <code>waitTime</code> milliseconds
133 * @throws InterruptedException
134 * if {@link Object#wait()} is interrupted
136 public R getResult(long waitTime) throws InterruptedException {
137 synchronized (syncObject) {
138 if (!resultComplete) {
139 syncObject.wait(waitTime);
146 * Returns the result even if it is not yet complete.
148 * @return The result of the operation
150 R getIntermediaryResult() {
151 synchronized (syncObject) {
157 * Marks the result as complete and notify the listeners. If the result was
158 * already complete, nothing will be done.
161 synchronized (syncObject) {
162 if (resultComplete) {
165 resultComplete = true;