package uc.files.search; import helpers.PreferenceChangedAdapter; import java.util.Collections; import java.util.Comparator; import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import logger.LoggerFactory; import org.apache.log4j.Logger; import uc.DCClient; import uc.PI; import uc.IStoppable.IStartable; import uc.crypto.HashValue; import uc.files.downloadqueue.AbstractFileDQE; import uc.files.search.SearchResult.ISearchResultListener; public class AutomaticSearchForAlternatives implements Runnable, ISearchResultListener ,IStartable { private static Logger logger = LoggerFactory.make(); private final Set<HashValue> alreadySearched = new HashSet<HashValue>(); private static final int SEARCHINTERVAL = PI.getInt(PI.autoSearchInterval) * 60 ; private ScheduledFuture<?> task = null; private final PreferenceChangedAdapter pca; private final DCClient dcc; private final Comparator<AbstractFileDQE> comp = new Comparator<AbstractFileDQE>() { public int compare(AbstractFileDQE o1, AbstractFileDQE o2) { int i = Integer.valueOf(o1.getNrOfUsers()).compareTo(o2.getNrOfUsers()); if (i == 0) { i = Integer.valueOf(o1.getNrOfRunningDownloads()).compareTo(o2.getNrOfRunningDownloads()); } if (i == 0) { //higher priority first.. i = -Integer.valueOf(o1.getPriority()).compareTo(o2.getPriority()); } return i; } }; public AutomaticSearchForAlternatives(DCClient dcc) { this.dcc = dcc; pca = new PreferenceChangedAdapter(PI.get(),PI.autoSearchForAlternates) { @Override public void preferenceChanged(String preference, String oldValue,String newValue) { boolean newVal = Boolean.valueOf(newValue); if (newVal) { startS(); } else { stopS(); } } }; } public void start() { startS(); pca.reregister(); } public void stop() { stopS(); pca.dispose(); } public void startS() { if (task == null) { dcc.register(this); task = dcc.getSchedulerDir().scheduleAtFixedRate( this,SEARCHINTERVAL,SEARCHINTERVAL, TimeUnit.SECONDS); } } public void stopS() { if (task != null) { dcc.unregister(this); task.cancel(false); task = null; } } private AbstractFileDQE nextOnSearch() { List<AbstractFileDQE> filedqes = dcc.getDownloadQueue().getAllFileDQE(); Collections.sort(filedqes,comp); for (AbstractFileDQE afdqe:filedqes) { if (!alreadySearched.contains(afdqe.getTTHRoot())) { return afdqe; } } return null; } public void run() { searchNext(); } public void searchNext() { AbstractFileDQE adqe = nextOnSearch(); if (adqe != null) { alreadySearched.add(adqe.getTTHRoot()); dcc.search( new FileSearch(adqe.getTTHRoot())); logger.debug("Searching for: "+adqe.getFileName()+" "+alreadySearched.size()); } else { alreadySearched.clear(); logger.debug("Clearing already searched"); } } public boolean isSearchForAlternatesEnabled() { return task != null; } public void received(ISearchResult sr) { //add user if file is already in Queue.. if (sr.isFile() && isSearchForAlternatesEnabled() && dcc.getDownloadQueue().containsDQE(sr.getTTHRoot())) { logger.debug("found alt: "+sr.getName()); sr.download(); } } }