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 public final Object syncObject = new Object();
40 /** The list of callback listeners. */
41 public final List<HighLevelCallbackListener<R>> highLevelCallbackListeners = Collections.synchronizedList(new ArrayList<HighLevelCallbackListener<R>>());
43 /** The result of the operation. */
44 public R result = null;
47 * Adds a callback listener to this callback. The callback listener will be
48 * called as soon as the result of the operation is known. If the result is
49 * already known, the listener will be called immediately. Also, as soon as
50 * a listener was notified the listener is automatically removed from this
53 * @param highLevelCallbackListener
56 public void addHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
57 highLevelCallbackListeners.add(highLevelCallbackListener);
64 * Removes a callback listener from this callback.
66 * @param highLevelCallbackListener
67 * The listener to remove
69 public void removeHighLevelCallbackListener(HighLevelCallbackListener<R> highLevelCallbackListener) {
70 highLevelCallbackListeners.remove(highLevelCallbackListener);
74 * Notifies all listeners that the result of the operation is now known.
76 * @see HighLevelCallbackListener#gotResult(HighLevelCallback)
78 private synchronized void fireGotResult() {
79 for (HighLevelCallbackListener<R> highLevelCallbackListener: highLevelCallbackListeners) {
80 highLevelCallbackListeners.remove(highLevelCallbackListener);
81 highLevelCallbackListener.gotResult(this);
86 * Returns whether the result of the operation is already known. If the
87 * result is already known a call to {@link #getResult()} will not block.
89 * @return <code>true</code> if the result is already known,
90 * <code>false</code> otherwise
92 public boolean isDone() {
93 synchronized (syncObject) {
94 return result != null;
99 * Returns the result of the operation, blocking until it is known.
101 * @return The result of the operation
102 * @throws InterruptedException
103 * if {@link Object#wait()} was interrupted
105 public R getResult() throws InterruptedException {
110 * Returns the result of the operation, blocking until it is known or the
111 * given time (in milliseconds) has passed.
114 * The time to wait for a result
115 * @return The result of the operation, or <code>null</code> if the result
116 * is still not known after <code>waitTime</code> milliseconds
118 * @throws InterruptedException
119 * if {@link Object#wait()} is interrupted
121 public R getResult(long waitTime) throws InterruptedException {
122 synchronized (syncObject) {
123 if (result == null) {
124 syncObject.wait(waitTime);
131 * Sets the result of the operation. Calling this method will result in all
132 * listeners being notified.
134 * @see #fireGotResult()
136 * The result of the operation
138 void setResult(R result) {
139 synchronized (syncObject) {
140 this.result = result;
141 syncObject.notifyAll();