/*
* Copyright 2006-2010 Daniel Henninger. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution.
*/
package net.sf.kraken.protocols.oscar;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.IdentityHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import net.kano.joscar.snac.SnacRequest;
import org.apache.log4j.Logger;
/**
* Handles incoming SNAC packets.
*
* @author Daniel Henninger
* Heavily inspired by joscardemo from the joscar project.
*/
public class SnacManager {
static Logger Log = Logger.getLogger(SnacManager.class);
protected Map<Integer,List<BasicFlapConnection>> conns = new HashMap<Integer,List<BasicFlapConnection>>();
protected PendingSnacMgr pendingSnacs = new PendingSnacMgr();
protected List<PendingSnacListener> listeners = new ArrayList<PendingSnacListener>();
protected Map<BasicFlapConnection,int[]> supportedFamilies = new IdentityHashMap<BasicFlapConnection,int[]>();
public SnacManager() { }
public SnacManager(PendingSnacListener listener) {
addListener(listener);
}
public void register(BasicFlapConnection conn) {
Log.debug("Registrating snac handler "+conn);
int[] families = conn.getSnacFamilies();
supportedFamilies.put(conn, families);
for (int familyCode : families) {
List<BasicFlapConnection> handlers = conns.get(familyCode);
if (handlers == null) {
handlers = new LinkedList<BasicFlapConnection>();
conns.put(familyCode, handlers);
}
if (!handlers.contains(conn)) {
handlers.add(conn);
}
}
}
public void dequeueSnacs(BasicFlapConnection conn) {
int[] infos = supportedFamilies.get(conn);
if (infos != null) {
for (int familyCode : infos) {
if (pendingSnacs.isPending(familyCode)) {
dequeueSnacs(familyCode);
}
}
}
}
protected void dequeueSnacs(int familyCode) {
List<SnacRequest> pending = pendingSnacs.getPending(familyCode);
pendingSnacs.setPending(familyCode, false);
for (PendingSnacListener listener : listeners) {
listener.dequeueSnacs(pending);
}
}
public void unregister(BasicFlapConnection conn) {
for (List<BasicFlapConnection> handlers : conns.values()) {
handlers.remove(conn);
}
}
public BasicFlapConnection getConn(int familyCode) {
List<BasicFlapConnection> handlers = conns.get(familyCode);
if (handlers == null || handlers.size() == 0) {
return null;
}
return handlers.get(0);
}
public boolean isPending(int familyCode) {
return pendingSnacs.isPending(familyCode);
}
public void addRequest(SnacRequest request) {
int family = request.getCommand().getFamily();
if (!isPending(family)) {
throw new IllegalArgumentException("Family 0x"
+ Integer.toHexString(family) + " is not pending");
}
pendingSnacs.add(request);
}
public void addListener(PendingSnacListener l) {
if (!listeners.contains(l)) {
listeners.add(l);
}
}
public void removeListener(PendingSnacListener l) {
listeners.remove(l);
}
public void setPending(int family, boolean pending) {
pendingSnacs.setPending(family, pending);
}
}