IncompleteFile.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
xnap.util |
![]() |
![]() |
XNap |
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.util;
import xnap.util.*;
import xnap.net.*;
import xnap.net.nap.*;
import java.util.*;
import java.io.*;
import java.beans.*;
/**
* Stores all information needed by ResumeScheduler to initiate searches and
* downloads in decent intervals.
*
* Handles searches and downloads too but is controlled by ResumeScheduler.
*/
public class IncompleteFile extends AbstractTransfer
implements Runnable, PropertyChangeListener
{
//--- Constant(s) ---
public final static int SEARCH_INTERVAL = 2 * 60 * 1000;
public final static int DOWNLOAD_INTERVAL = 1 * 60 * 1000;
//--- Data field(s) ---
private Preferences prefs = Preferences.getInstance();
private int downloadCount = 0;
private int searchCount = 0;
private long finalSize;
private long initialSize;
private SimpleCollector srCollector;
private AbstractSearchFilter filter;
private AbstractDownload download = null;
private int status = 0;
private Thread thread = null;
private Object lock = new Object();
private boolean die = false;
private ObservableVector servers = Connector.getInstance().getServers();
//--- Constructor(s) ---
public IncompleteFile(File f, long size)
{
file = f;
finalSize = size;
initialSize = f.length();
srCollector = new SimpleCollector();
filter =
new xnap.net.nap.SearchFilter("", AbstractSearchFilter.COMPARE_NOT_ACTIVE,
"", AbstractSearchFilter.MEDIA_ANYTHING,
size);
}
public IncompleteFile(File f, long size, AbstractSearchResult asr)
{
this(f, size);
srCollector.add(asr);
}
public IncompleteFile(File f, long size, AbstractSearchResult asr,
String searchText)
{
this(f, size, asr);
filter.setSearchText(searchText);
}
//--- Method(s) ---
public void delete()
{
abort();
file.delete();
}
public void resume()
{
if (thread != null && thread.isAlive()) {
die = false;
wakeup();
return;
}
downloadCount = 0;
searchCount = 0;
thread = new Thread(this);
die = false;
thread.start();
}
public void abort()
{
abort(null);
}
public void abort(String statusText)
{
die = true;
setStatus(STATUS_ABORTED, statusText);
if (download != null) {
download.abort();
cleanup();
}
wakeup();
if (thread != null)
thread.interrupt();
}
/**
* Cleans up after abort. Is separated from abort to be called as well when
* status is STATUS_INCOMPLETE or STATUS_FAILED.
*/
private void cleanup()
{
if (download != null) {
Debug.log("Cleaning up download");
download.removePropertyChangeListener(this);
download = null;
}
}
public void setDownload(AbstractDownload ad)
{
download = ad;
download.addPropertyChangeListener(this);
}
public void run()
{
while (download == null || download.getStatus() !=
AbstractTransfer.STATUS_FINISHED) {
if (die)
return;
if (downloadCount > 32 ||searchCount > 5)
abort("N/A");
/* perform search */
search();
sleep(SEARCH_INTERVAL);
Debug.log("No. of searchresults for " + filter.getSearchText()
+ ": " + srCollector.size());
while (srCollector.size() > 0) {
if (die)
return;
Debug.log("Download: " + download);
downloadCount++;
Debug.log("downloadCount: " + downloadCount);
AbstractSearchResult sr
= (AbstractSearchResult)srCollector.remove(0);
download = sr.getDownload(prefs.getIncompleteDir(),
prefs.getDownloadDir(),
file);
download.addPropertyChangeListener(this);
download.start();
/* sleep without timeout means we totally rely on downloads to
send the right status messages on time in order to prevent us
from deadlocking */
sleep();
while (download != null && download.getStatus()
== AbstractTransfer.STATUS_DOWNLOADING) {
if (die)
return;
sleep();
}
if (download!= null &&
download.getStatus() == AbstractTransfer.STATUS_FINISHED) {
download.removePropertyChangeListener(this);
/* rename file */
String completeName = prefs.getDownloadDir() +
download.getSearchResult().getShortFilename();
File newFile = new File(Filename.uniqueFilename(completeName));
boolean complete = file.renameTo(newFile);
if (complete) {
file = newFile;
setStatus(STATUS_FINISHED);
}
else
setStatus(STATUS_FAILED,
"download directory (check preferences)");
die = true;
return;
}
}
}
}
/**
* Observes the download threads.
*/
public void propertyChange(PropertyChangeEvent e)
{
Object source = e.getSource();
if (source instanceof AbstractDownload) {
Debug.log(filter.getSearchText());
Debug.log("dl status: "
+ ((AbstractDownload) source).getStatusText());
int status = ((AbstractDownload) source).getStatus();
Object o;
switch(status) {
case AbstractTransfer.STATUS_REMOTELY_QUEUED:
if (download != null) {
download.abort();
}
break;
case AbstractTransfer.STATUS_FINISHED:
wakeup();
break;
case AbstractTransfer.STATUS_FAILED:
cleanup();
wakeup();
break;
case AbstractTransfer.STATUS_INCOMPLETE:
cleanup();
wakeup();
break;
case AbstractTransfer.STATUS_ABORTED:
cleanup();
wakeup();
break;
default:
break;
}
}
else if (source instanceof AbstractSearch) {
Debug.log("s status: "
+ ((AbstractSearch) source).getStatusText());
int status = ((AbstractSearch) source).getStatus();
AbstractSearch search = (AbstractSearch) source;
switch (status) {
case AbstractSearch.STATUS_FAILED:
search.removePropertyChangeListener(this);
break;
case AbstractSearch.STATUS_FINISHED:
Debug.log("No. of searchresults for " + filter.getSearchText()
+ ": " + srCollector.getRowCount());
search.removePropertyChangeListener(this);
if (srCollector.getRowCount() > 0 && download == null)
wakeup();
break;
default:
break;
}
}
}
/**
* keyword synchronized should be fatal here since java is reentrant on
* threads.
*/
private synchronized void sleep()
{
sleep(0);
}
private synchronized void sleep(long timeout)
{
try {
wait(timeout);
}
catch (InterruptedException ie) {
}
}
private synchronized void wakeup()
{
notify();
}
public String getFilename()
{
return file.getName();
}
public long getFilesize()
{
return finalSize;
}
public long getBytesTransferred()
{
if (download != null)
return download.getBytesTransferred();
return file.length();
}
public long getCurrentRate()
{
if (download != null)
return download.getCurrentRate();
return -1;
}
public String getSearchText()
{
return filter.getSearchText();
}
public void setSearchText(String newValue)
{
filter.setSearchText(newValue);
}
public String getStatusText() {
if (download != null)
return download.getStatusText();
return super.getStatusText();
}
private void search()
{
long timeout;
while ((timeout = SEARCH_INTERVAL - getElapsedTime()) > 0) {
if (die)
return;
Debug.log("Elapsed time is: " + getElapsedTime());
Debug.log("Waiting " + timeout + " for next search");
sleep(timeout);
}
Server s;
HashSet set = new HashSet();
int serverCount = 0;
String searchText = filter.getSearchText();
if (searchText.equals("")) {
try {
searchText =
file.getName().substring(0, file.getName().indexOf("."));
searchText.replace('-', ' ');
filter.setSearchText(searchText);
}
catch (StringIndexOutOfBoundsException e) {
filter.setSearchText(file.getName());
}
}
Debug.log("Search text is " + filter.getSearchText());
setStatus(STATUS_SEARCHING);
startTransfer();
searchCount++;
Debug.log("searchCount: " + searchCount);
for (int i = 0; (i < servers.size()
&& (prefs.getMaxSearchServers() == 0
|| serverCount < prefs.getMaxSearchServers()));
i++) {
s = (Server) servers.get(i);
if (s.getStatus() == Server.STATUS_CONNECTED) {
if (s.getNetwork().equals("") || set.add(s.getNetwork())) {
xnap.net.nap.Search search = new xnap.net.nap.Search
(filter, prefs.getMaxSearchResults(), srCollector,
s);
(new Thread(search)).start();
search.addPropertyChangeListener(this);
serverCount++;
}
}
}
}
/**
* Simple private class extends Vector to implement the
* SearchResultCollector interface.
*/
private class SimpleCollector extends Vector
implements SearchResultCollector
{
public int getRowCount()
{
return size();
}
public void add(AbstractSearchResult sr)
{
super.add(sr);
}
}
}
The table below shows all metrics for IncompleteFile.java.




