Skip to content

Instantly share code, notes, and snippets.

@Ribesg
Last active August 29, 2015 13:57
Show Gist options
  • Save Ribesg/9531370 to your computer and use it in GitHub Desktop.
Save Ribesg/9531370 to your computer and use it in GitHub Desktop.
package fr.ribesg.alix.api.sync;
import fr.ribesg.alix.api.message.IrcPacket;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
/**
* Represents a Callback for a sent IrcPacket.
*/
public abstract class Callback {
/**
* Default Timeout, in milliseconds: 30 seconds
*/
private static final long DEFAULT_TIMEOUT = 30 * 1_000;
/**
* Set of listened Commands and Reply codes
*/
private final Set<String> listenedCodes;
/**
* Time after which this Callback should call {@link #timeout} and be
* destroyed.
*/
private final long timeoutDuration;
/**
* The Original IRC Packet for which the Callback was set up.
* <p/>
* Should be set by the send-like methods to be more user-friendly than
* the User having to repeat the original IRC Packet twice in the method
* call.
*/
private IrcPacket originalIrcPacket;
/**
* Callback constructor.
* <p/>
* Pass some {@link fr.ribesg.alix.api.enums.Command} and/or some
* {@link fr.ribesg.alix.api.enums.Reply} codes to it to restrict
* calls to {@link #onIrcPacket(IrcPacket)} to them.
* <p/>
* If no argument is passed, {@link #onIrcPacket(IrcPacket)} will be
* called for every incoming {@link IrcPacket} until the method
* returns true.
* <p/>
* Of course listened Codes have to be uppercase to follow IRC RFCs.
*
* @param timeoutDuration the time after which this Callback should call
* {@link #timeout} and be destroyed, in
* milliseconds
* @param listenedCodes listened Commands and Reply codes, can be empty
* to listen to everything
*/
public Callback(final long timeoutDuration, final String... listenedCodes) {
this.timeoutDuration = timeoutDuration;
if (listenedCodes.length != 0) {
this.listenedCodes = new HashSet<>();
Collections.addAll(this.listenedCodes, listenedCodes);
} else {
this.listenedCodes = null;
}
}
public Set<String> getListenedCodes() {
return listenedCodes;
}
public long getTimeoutDuration() {
return timeoutDuration;
}
public IrcPacket getOriginalIrcPacket() {
return originalIrcPacket;
}
/**
* You should not call this.
* <p/>
* This should only be called by the Server's send-like methods to link
* the original IrcPacket to its Callback, for the user not to have to
* do it.
*/
public void setOriginalIrcPacket(final IrcPacket originalIrcPacket) {
this.originalIrcPacket = originalIrcPacket;
}
/**
* This method will be called for every received {@link IrcPacket} that
* this Callback listens to, or everyone of them if
* {@link #listenedCodes} is null.
* <p/>
* If the method returns false, this means that the passed
* {@link IrcPacket} is not the one which was awaited. The Callback will
* continue to receive {@link IrcPacket}s to handle.
* <p/>
* If the method returns true, this means that the passed
* {@link IrcPacket} is the awaited one. The Callback will stop receiving
* {@link IrcPacket} and will be destroyed.
* <p/>
* Please @see #timeout()
*
* @param packet a received IrcPacket matching {@link #listenedCodes} if
* defined, any received IrcPacket otherwise
*
* @return true if the received IrcPacket was the one which was awaited,
* false otherwise
*/
protected abstract boolean onIrcPacket(final IrcPacket packet);
/**
* This method will be called when this Callback times out.
* <p/>
* The default implementation is to throw an
* {@link UnexpectedTimeoutException} to say that it's not implemented.
*/
protected void timeout() {
throw new UnexpectedTimeoutException(originalIrcPacket, timeoutDuration);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment