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>
34 public class HighLevelCallback<R extends HighLevelResult> {
36 /** Object used for synchronization. */
37 protected final Object syncObject = new Object();
39 /** The list of callback listeners. */
40 private final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
42 /** Whether the result is complete. */
43 protected boolean resultComplete = false;
45 /** The result of the operation. */
46 private R result = null;
49 * Package-private construtor.
52 * The result of the operation
54 HighLevelCallback(R result) {
59 * Adds a callback listener to this callback. The callback listener will be
60 * called as soon as the result of the operation is known. If the result is
61 * already known, the listener will be called immediately. Also, as soon as
62 * a listener was notified the listener is automatically removed from this
65 * @param highLevelCallbackListener
68 public void addHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
69 highLevelCallbackListeners.add(highLevelCallbackListener);
76 * Removes a callback listener from this callback.
78 * @param highLevelCallbackListener
79 * The listener to remove
81 public void removeHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
82 highLevelCallbackListeners.remove(highLevelCallbackListener);
86 * Notifies all listeners that the result of the operation is now known. As
87 * soon as a listener was notified it will be removed from the list of
90 * @see HighLevelCallbackListener#gotResult(HighLevelCallback)
92 private synchronized void fireGotResult() {
93 for (HighLevelCallbackListener<R> highLevelCallbackListener: highLevelCallbackListeners) {
94 highLevelCallbackListener.gotResult(this);
96 highLevelCallbackListeners.clear();
100 * Returns whether the result of the operation is already known. If the
101 * result is already known a call to {@link #getResult()} will not block.
103 * @return <code>true</code> if the result is already known,
104 * <code>false</code> otherwise
106 public boolean isDone() {
107 synchronized (syncObject) {
108 return resultComplete;
113 * Returns the result of the operation, blocking until it is known.
115 * @return The result of the operation
116 * @throws InterruptedException
117 * if {@link Object#wait()} was interrupted
119 public R getResult() throws InterruptedException {
124 * Returns the result of the operation, blocking until it is known or the
125 * given time (in milliseconds) has passed.
128 * The time to wait for a result
129 * @return The result of the operation, or <code>null</code> if the result
130 * is still not known after <code>waitTime</code> milliseconds
132 * @throws InterruptedException
133 * if {@link Object#wait()} is interrupted
135 public R getResult(long waitTime) throws InterruptedException {
136 synchronized (syncObject) {
137 while (!resultComplete) {
138 syncObject.wait(waitTime);
145 * Returns the result even if it is not yet complete.
147 * @return The result of the operation
149 R getIntermediaryResult() {
150 synchronized (syncObject) {
156 * Marks the result as complete and notify the listeners. If the result was
157 * already complete, nothing will be done.
160 synchronized (syncObject) {
161 if (resultComplete) {
164 resultComplete = true;
165 syncObject.notifyAll();