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 private 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 /** The result of the operation. */
44 private R result = null;
47 * Package-private construtor.
53 * Adds a callback listener to this callback. The callback listener will be
54 * called as soon as the result of the operation is known. If the result is
55 * already known, the listener will be called immediately. Also, as soon as
56 * a listener was notified the listener is automatically removed from this
59 * @param highLevelCallbackListener
62 public void addHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
63 highLevelCallbackListeners.add(highLevelCallbackListener);
70 * Removes a callback listener from this callback.
72 * @param highLevelCallbackListener
73 * The listener to remove
75 public void removeHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
76 highLevelCallbackListeners.remove(highLevelCallbackListener);
80 * Notifies all listeners that the result of the operation is now known.
82 * @see HighLevelCallbackListener#gotResult(HighLevelCallback)
84 private synchronized void fireGotResult() {
85 for (HighLevelCallbackListener<R> highLevelCallbackListener: highLevelCallbackListeners) {
86 highLevelCallbackListeners.remove(highLevelCallbackListener);
87 highLevelCallbackListener.gotResult(this);
92 * Returns whether the result of the operation is already known. If the
93 * result is already known a call to {@link #getResult()} will not block.
95 * @return <code>true</code> if the result is already known,
96 * <code>false</code> otherwise
98 public boolean isDone() {
99 synchronized (syncObject) {
100 return result != null;
105 * Returns the result of the operation, blocking until it is known.
107 * @return The result of the operation
108 * @throws InterruptedException
109 * if {@link Object#wait()} was interrupted
111 public R getResult() throws InterruptedException {
116 * Returns the result of the operation, blocking until it is known or the
117 * given time (in milliseconds) has passed.
120 * The time to wait for a result
121 * @return The result of the operation, or <code>null</code> if the result
122 * is still not known after <code>waitTime</code> milliseconds
124 * @throws InterruptedException
125 * if {@link Object#wait()} is interrupted
127 public R getResult(long waitTime) throws InterruptedException {
128 synchronized (syncObject) {
129 if (result == null) {
130 syncObject.wait(waitTime);
137 * Sets the result of the operation. Calling this method will result in all
138 * listeners being notified.
140 * @see #fireGotResult()
142 * The result of the operation
144 void setResult(R result) {
145 synchronized (syncObject) {
146 this.result = result;
147 syncObject.notifyAll();