AutoDownload.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
xnap.net |
![]() |
![]() |
XNap 2 |
View: Reasons, Metrics, Source Code
These are the metrics that contribute to the Enerjy Score for this file, ranked by impact. So the metrics listed at the top influence the score to a greater extent that the metrics listed at the bottom.
/*
* XNap
*
* A pure java file sharing client.
*
* See AUTHORS for copyright information.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
package xnap.net;
import xnap.XNap;
import xnap.io.*;
import xnap.net.event.*;
import xnap.plugin.PluginManager;
import xnap.util.*;
import xnap.util.event.*;
import java.util.*;
import java.io.*;
public class AutoDownload extends MultiDownload
implements IDownloadContainer, StatusChangeListener, ListListener,
Runnable {
//--- Constant(s) ---
/**
* Research interval. (default 30 minutes).
*/
public static long MAX_SEARCH_INTERVAL = 3 * 60 * 60 * 1000;
/**
* If no searches can be spawned, try again every 45 seconds.
*/
public static final long FAILED_SEARCH_INTERVAL = 45 * 1000;
//--- Data field(s) ---
private SearchResultCollector srCollector;
private SearchFilter filter;
private SearchThread st = new SearchThread();
private Hashtable downloads = new Hashtable();
private ISearchResult[] orgResults = null;
private Preferences prefs = Preferences.getInstance();
private long searchInterval;
//--- Constructor(s) ---
public AutoDownload(ResumeFile3 file)
{
initialize(file);
}
public AutoDownload(ISearchResult results[], SearchFilter filter,
File resumeFrom)
{
ISearchResult sr = results[0];
if (resumeFrom == null) {
try {
String filename = sr.getShortFilename();
// add final filesize to filename to make it easier to
// resume file by hand
// int i = filename.lastIndexOf(".");
// if (i < 0 || i == filename.length() - 1) {
// filename += "." + sr.getFilesize();
// }
// else {
// filename
// = filename.substring(0, i + 1)
// + sr.getFilesize() + "."
// + filename.substring(i + 1, filename.length());
// }
String path = prefs.getIncompleteDir();
resumeFrom = FileHelper.createUnique(path, filename);
}
catch (IOException e) {
setStatus(STATUS_ERROR, XNap.tr("Could not create file, make sure the incomplete directory is writeable."));
return;
}
}
if (!resumeFrom.canWrite()) {
setStatus(STATUS_ERROR, XNap.tr("Can not write to incomplete file."));
return;
}
ResumeFile3 file
= new ResumeFile3(resumeFrom, sr.getFilesize(),
SearchFilterHelper.convert(filter.getData()));
ResumeRepository.getInstance().add(file);
initialize(file);
addResults(results);
if (filter == null) {
// keep original results for browses
this.orgResults = results;
}
}
/**
* Used to resume from file.
*/
public AutoDownload(ISearchResult[] results, SearchFilter filter)
{
this(results, filter, null);
}
//--- Method(s) ---
public void initialize(ResumeFile3 file)
{
logger.debug("resuming " + file);
filter = new SearchFilter
(SearchFilterHelper.convert(file.getFilterData()));
filter.setFilesize(file.getFinalSize());
filter.setFilesizeCompare(SearchFilter.COMPARE_EQUAL_TO);
setResumeFile(file);
addStatusChangeListener(this);
// the search result collector should not double filter by searchtext
// or media type
SearchFilter srFilter = (SearchFilter)filter.clone();
srFilter.setSearchText("");
srFilter.setMediaType(SearchFilter.MEDIA_ANYTHING);
srCollector = new SearchResultCollector(srFilter, new Grouper());
srCollector.getGroupedData().addListListener(this);
}
public boolean add(ISearchResult result)
{
if (result.canGroup() && result instanceof AbstractSearchResult) {
AbstractSearchResult s = (AbstractSearchResult)result;
IDownload d = s.getDownload();
if (add(d)) {
downloads.put(d, result);
st.incDownloadCount();
return true;
}
}
return false;
}
public void elementAdded(ListEvent e)
{
SearchResultContainer sr
= (SearchResultContainer)e.getElement();
ISearchResult[] results = sr.getSearchResults();
for (int i = 0; i < results.length; i++) {
add(results[i]);
}
}
public void elementRemoved(ListEvent e)
{
}
public void die()
{
super.die();
st.die();
}
public boolean isResumeCapable()
{
return filter.getSearchText().length() > 0;
}
public SearchFilter getSearchFilter()
{
return filter;
}
/**
* Also remove associated search result so we can find download again.
*/
public void remove(IDownload d)
{
super.remove(d);
ISearchResult sr = (ISearchResult)downloads.get(d);
if (sr != null) {
logger.info("download failed, removing from search results: " + sr);
srCollector.remove(sr);
}
}
public void statusChange(StatusChangeEvent e)
{
if (isResumeCapable()) {
if (isDone() || !isBusy()) {
st.wakeup();
}
}
else {
if (isDone()) {
boolean del = prefs.getDelIncompleteFiles();
if (getStatus() != STATUS_SUCCESS && del) {
// what the freaking heck?!
//getFile().delete();
}
}
else if (getStatus() == STATUS_WAITING && getQueueSize() == 0
&& prefs.getLimitDownloadAttempts()) {
fail("N/A");
return;
}
}
}
public void start()
{
//reset search interval.
searchInterval
= Preferences.getInstance().getAutoDownloadSearchInterval() * 1000;
reset();
super.start();
if (isResumeCapable()) {
Thread searchRunner = new Thread(st, toString());
searchRunner.start();
}
else {
clear();
addResults(orgResults);
}
}
public String toString()
{
File f = getFile();
return "AutoDownload " + ((f != null) ? f.getName() : "(error)");
}
/**
* Called by AutoDownloadEditorDialog.
*/
public void updatedSearchFilter()
{
// ugly hack to update table
setStatus(getStatus());
}
protected void addResults(ISearchResult[] results)
{
if (results != null) {
for (int i = 0; i < results.length; i++) {
add(results[i]);
}
}
}
protected class SearchThread implements Runnable
{
public int downloadCount = 0;
private int searchCount = 0;
private Object lock = new Object();
private boolean die = false;
protected Searcher sr = null;
protected long lastSearch;
public void die()
{
die = true;
wakeup();
}
public void incDownloadCount()
{
downloadCount++;
}
public void run()
{
downloadCount = 0;
searchCount = 0;
lastSearch = 0;
die = false;
while (!die && !isDone()) {
if (prefs.getLimitDownloadAttempts()
&& (searchCount > prefs.getAutoDownloadMaxSearches())
&& (getQueueSize() == 0)) {
fail("N/A");
break;
}
if (!isBusy() && searchCount == 0) {
// this is a resume
doSearch();
}
synchronized (this.lock) {
while (!die && !isDone() && (isBusy() || waitFor() > 0)) {
if (isBusy()) {
// wait until download is finished or aborted
// we don't want to do too many senseless searches
logger.debug("AutoDownload: waiting");
this.waitLock();
}
else {
logger.debug("AutoDownload: waiting for "
+ waitFor());
this.waitLock(waitFor());
}
}
}
if (!die && !isDone()) {
doSearch();
}
}
stopSearch();
srCollector.clear();
logger.debug("AutoDownload: finished");
}
public void stopSearch()
{
if (sr != null) {
sr.abort();
}
}
/**
* Returns the amount of time we should wait until the next search.
*/
public long waitFor()
{
long elapsed = System.currentTimeMillis() - lastSearch;
if (sr != null && sr.getSize() == 0) {
return FAILED_SEARCH_INTERVAL - elapsed;
}
else {
return searchInterval - elapsed;
}
}
public void wakeup()
{
synchronized (this.lock) {
this.lock.notify();
}
}
protected void doSearch()
{
stopSearch();
// perform search
logger.debug("AutoDownload: searching");
// disabling this stuff for now...
// if (getQueueSize() > 0 ) {
// logger.debug("getQueueSize > 0, not doing search");
// searchCount++;
// lastSearch = System.currentTimeMillis();
// return;
// }
if (getStatus() == STATUS_WAITING
|| getStatus() == STATUS_NOT_STARTED) {
setStatus(STATUS_SEARCHING);
}
ISearch[] searches = PluginManager.getInstance().search
(filter, ISearch.PRIORITY_BACKGROUND);
sr = new Searcher(searches, filter, srCollector);
sr.start();
//if (sr.getCollector().getResults().length == 0) {
searchInterval *= 2;
// upper bound is 3h to prevent needlessly long intervals.
searchInterval = Math.min(searchInterval, MAX_SEARCH_INTERVAL);
logger.debug("increased search intervall: " + searchInterval);
//}
searchCount++;
lastSearch = System.currentTimeMillis();
}
protected void waitLock(long time)
{
if (time <= 0) {
return;
}
synchronized (this.lock) {
try {
this.lock.wait(time);
}
catch (InterruptedException e) {
}
}
}
protected void waitLock()
{
synchronized (lock) {
try {
this.lock.wait();
}
catch (InterruptedException e) {
}
}
}
}
}
The table below shows all metrics for AutoDownload.java.




