package eu.jucy.op; import java.io.File; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Queue; import java.util.Set; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.regex.Pattern; import logger.LoggerFactory; import org.apache.log4j.Logger; import uc.IHub; import uc.IOperatorPlugin; import uc.IUser; import uc.HubListenerAdapter; import uc.files.downloadqueue.AbstractDownloadQueueEntry; import uc.files.downloadqueue.FileListDQE; import uc.files.downloadqueue.AbstractDownloadFinished; import uc.protocols.ConnectionProtocol; import uc.protocols.ConnectionState; public class OperatorPlugin extends HubListenerAdapter implements IOperatorPlugin { public static Logger logger = LoggerFactory.make(); // private static OperatorPlugin singleton; // // public static OperatorPlugin get() { // if (singleton == null) { // throw new IllegalStateException("OP plugin Not yet created"); // } // return singleton; // } private Pattern protectedUsr; private final Set<IHub> controlledHubs = new HashSet<IHub>(); /** * map checked user to resultObjects.. */ private final Map<IUser,Object> checkedUser = Collections.synchronizedMap(new WeakHashMap<IUser,Object>()); private final Queue<IUser> needsCheck = new ConcurrentLinkedQueue<IUser>(); // new LinkedList<IUser>(); private final Map<IUser,AbstractDownloadQueueEntry> inCheck = Collections.synchronizedMap(new HashMap<IUser,AbstractDownloadQueueEntry>()); public OperatorPlugin() { update(); // if (singleton != null) { // throw new IllegalStateException("Op plugin already initialized"); // } // singleton = this; } private final void update() { protectedUsr = Pattern.compile(OPI.get(OPI.protectedUsersRegEx)); } /* * (non-Javadoc) * @see UC.IOperatorPlugin#init(UC.IHub) */ public boolean init(IHub hub) { String check = hub.getFavHub().get(OPI.fh_checkUsers); if (Boolean.parseBoolean(check) && OPI.getBoolean(OPI.checkUsers)) { controlledHubs.add(hub); return true; } return false; } /* * (non-Javadoc) * @see UC.OperatorPluginAdapter#statusChanged(UC.protocols.ConnectionState, UC.protocols.ConnectionProtocol) */ @Override public void statusChanged(ConnectionState newStatus, ConnectionProtocol cp) { if (ConnectionState.DESTROYED.equals(newStatus)) { controlledHubs.remove(cp); } } /* * (non-Javadoc) * @see UC.OperatorPluginAdapter#changed(UC.IUser, UC.listener.IUserChangedListener.UserChange) */ public void changed(UserChangeEvent uce) { IUser changed = uce.getChanged(); switch(uce.getType()) { case CONNECTED: if (shouldCheckUsr(changed)) { needsCheck.offer(changed); if (inCheck.size() < OPI.getInt(OPI.parallelChecks)) { addCheckItem(); } } break; case QUIT: case DISCONNECTED: AbstractDownloadQueueEntry adqe; if ((needsCheck.remove(changed) | null != (adqe=inCheck.remove(changed))) && adqe != null) { adqe.remove(); } } } public boolean isInCheck(IUser usr) { return inCheck.containsKey(usr); } /** * polls next user and starts checking process.. */ private void addCheckItem() { final IUser usr = needsCheck.poll();; if (usr != null) { FileListDQE fdqe = usr.downloadFilelist(); inCheck.put(usr,fdqe); fdqe.addDoAfterDownload(new AbstractDownloadFinished() { public void finishedDownload(File f) { logger.debug("do after download: "+usr.getNick()); //this is called after the filelist check.. inCheck.remove(usr); addCheckItem(); } }); } } /** * * @param usr - usr that might need checking * @return true if the User needs to be checked.. */ private boolean shouldCheckUsr(IUser usr) { return !usr.isOp() && ! (usr.getShared() <= 0) && !protectedUsr.matcher(usr.getNick()).matches() && !checkedUser.containsKey(usr); } public void checkedUser(IUser checked) { checkedUser.put(checked, new Object()); //TODO check information object.. } public CheckState getCheckState(IUser who) { if (controlledHubs.contains(who.getHub())) { if (inCheck.containsKey(who)) { return CheckState.CHECKING; } if (needsCheck.contains(who)) { return CheckState.SCHEDULED_FOR_CHECK; } if (checkedUser.containsKey(who)) { return CheckState.CHECKED; } } return CheckState.UNCHECKED; } }