TransferQueue.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
xnap.util |
![]() |
![]() |
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.util;
import xnap.cmdl.*;
import xnap.net.*;
import xnap.net.event.*;
import xnap.util.event.*;
import xnap.util.Formatter;
import java.beans.*;
import java.io.*;
import java.util.*;
import org.apache.log4j.Logger;
public abstract class TransferQueue extends EventVector
implements Runnable, StatusChangeListener {
//--- Constant(s) ---
public static final int WAKEUP_INTERVAL = 30;
//--- Data field(s) ---
protected static Preferences prefs = Preferences.getInstance();
private static TransferLogger tlog = null;
static {
LogListener l = new LogListener();
prefs.addPropertyChangeListener("logTransfersToFile", l);
prefs.addPropertyChangeListener("transferLogFile", l);
l.update();
}
protected Logger logger = Logger.getLogger(TransferQueue.class);
protected boolean clearAll;
protected StatusListener listener;
protected ITransferContainer[] lastTransfers;
protected Object lock = new Object();
private long currentRate = 0;
private LinkedList localQueue = new LinkedList();
private LinkedList runQueue = new LinkedList();
private int maxTransfers = 0;
private DeleteListener autoDeleter = new DeleteListener();
//--- Constructor(s) ---
/**
* @param clearAll clear all finished transfers, including aborted ones
*/
public TransferQueue(String name, boolean clearAll)
{
this.clearAll = clearAll;
Thread runner = new Thread(this, name);
runner.start();
}
public TransferQueue(String name)
{
this(name, true);
}
//--- Method(s) ---
public boolean abort(ITransferContainer t)
{
if (t.isRunning()) {
t.abort();
return true;
}
return false;
}
public void add(ITransferContainer t)
{
super.add(t);
t.addStatusChangeListener(autoDeleter);
}
public boolean canStart(ITransferContainer t)
{
return true;
}
public void clearFinished()
{
for (Iterator i = super.iterator(); i.hasNext();) {
ITransferContainer t = (ITransferContainer)i.next();
if (t.isDone()
&& (clearAll
|| t.getStatus() == ITransferContainer.STATUS_SUCCESS
|| t.getStatus() == ITransferContainer.STATUS_DELETED
|| t.getStatus() == ITransferContainer.STATUS_ERROR)) {
super.remove(i, t);
}
}
}
protected boolean isFull()
{
return getRunning() >= maxTransfers;
}
public int getMaxTransfers()
{
return maxTransfers;
}
protected int getRunning()
{
return runQueue.size();
}
public ITransferContainer[] getTransfers()
{
ITransferContainer[] array = new ITransferContainer[super.size()];
System.arraycopy(super.toArray(), 0, array, 0, array.length);
return array;
}
public static synchronized void log(ITransferContainer t)
{
if (tlog != null) {
try {
tlog.write(t);
}
catch (IOException e) {
Logger.getLogger(TransferQueue.class).warn
("could not write log entry", e);
tlog.close();
tlog = null;
}
}
}
public void remove(ITransferContainer t)
{
super.remove(t);
}
public void run()
{
synchronized (lock) {
while (true) {
Iterator i = localQueue.iterator();
while (i.hasNext() && (getRunning() < maxTransfers
|| maxTransfers == 0)) {
ITransferContainer t = (ITransferContainer)i.next();
if (t.getStatus()
!= ITransferContainer.STATUS_LOCALLY_QUEUED) {
// the transfer has been canceled in the mean time
i.remove();
}
else if (canStart(t)) {
i.remove();
startTransfer(t);
// give the transfer a chance to start running
// and to set the user limits
try {
Thread.currentThread().sleep(20);
}
catch (InterruptedException e) {
}
}
}
try {
// we should wake up every once in while
// sometimes user settings change and we need to recheck
lock.wait(WAKEUP_INTERVAL);
}
catch (InterruptedException e) {
}
}
}
}
public void setCurrentRate(long newValue)
{
currentRate = newValue;
updateStatus();
}
public void setMaxTransfers(int newValue)
{
maxTransfers = newValue;
wakeup();
}
public void statusChange(StatusChangeEvent e)
{
ITransferContainer t = (ITransferContainer)e.getSource();
if (t.isDone()) {
log(t);
logger.debug("done: " + t);
stopTransfer(t);
wakeup();
}
}
public void updateStatus()
{
synchronized (lock) {
if (listener != null) {
StringBuffer sb = new StringBuffer();
sb.append(getRunning());
sb.append(" (");
sb.append(Formatter.formatSize(currentRate));
sb.append("/s)");
listener.setStatus(sb.toString());
}
}
}
public void setStatusListener(StatusListener newValue)
{
synchronized (lock) {
listener = newValue;
updateStatus();
}
}
/**
* Called by child classes to add a new transfer.
*/
protected boolean enqueue(ITransferContainer t, boolean startAtOnce)
{
if (t.isResumable()) {
if (startAtOnce) {
startTransfer(t);
}
else {
logger.debug("enqueued " + t);
synchronized (lock) {
t.locallyQueued();
localQueue.addLast(t);
}
wakeup();
}
}
else {
logger.debug("enque failed: not resumable " + t);
return false;
}
return true;
}
protected boolean enqueue(ITransferContainer t)
{
return enqueue(t, false);
}
public int getLocalQueuePos(ITransferContainer t)
{
synchronized (lock) {
return localQueue.indexOf(t);
}
}
protected boolean isQueued(ITransferContainer t)
{
synchronized (lock) {
return localQueue.contains(t);
}
}
protected boolean isRunning(ITransferContainer t)
{
synchronized (lock) {
return runQueue.contains(t);
}
}
protected void print()
{
lastTransfers = getTransfers();
String[] table = new String[lastTransfers.length];
for (int i = 0; i < lastTransfers.length; i++) {
ITransferContainer t = lastTransfers[i];
StringBuffer sb = new StringBuffer();
sb.append(i);
File f = t.getFile();
sb.append("|" + ((f != null) ? f.getName() : ""));
sb.append("|" + t.getStatusText());
Progress p = new Progress(t.getTotalBytesTransferred(),
t.getFilesize(), t.getCurrentRate());
sb.append("|" + Formatter.formatNumber(p.progress, 2) + "%");
sb.append("|" + p.toString());
table[i] = sb.toString();
}
int L = Formatter.LEFT;
int R = Formatter.RIGHT;
int[] cols = new int[] { R, L, L, R, R };
Console.getInstance().println(Formatter.formatTable(table, cols));
}
protected void startTransfer(ITransferContainer t)
{
synchronized (lock) {
if (!runQueue.contains(t)) {
runQueue.add(t);
t.addStatusChangeListener(this);
t.start();
}
}
updateStatus();
}
private void stopTransfer(ITransferContainer t)
{
synchronized (lock) {
if (runQueue.remove(t)) {
t.removeStatusChangeListener(this);
}
else {
// the transfer has not been started, yet
localQueue.remove(t);
}
}
updateStatus();
}
public void stopAll()
{
for (Iterator i = super.iterator(); i.hasNext();) {
ITransferContainer t = (ITransferContainer)i.next();
stopTransfer(t);
}
}
protected void wakeup()
{
synchronized (lock) {
lock.notify();
}
}
private class DeleteListener implements StatusChangeListener
{
public void statusChange(StatusChangeEvent e)
{
ITransferContainer t = (ITransferContainer)e.getSource();
if (t.getStatus() == ITransferContainer.STATUS_DELETED) {
t.removeStatusChangeListener(this);
remove(t);
}
}
}
private static class LogListener implements PropertyChangeListener
{
public void propertyChange(PropertyChangeEvent e)
{
update();
}
public void update()
{
if (prefs.getLogTransfersToFile()) {
if (tlog == null) {
try {
tlog = new TransferLogger(prefs.getTransferLogFile());
}
catch (IOException e) {
Logger.getLogger(TransferQueue.class).warn
("could not get transfer log file");
return;
}
}
try {
tlog.setFilename(prefs.getTransferLogFile());
}
catch (IOException e) {
tlog = null;
}
}
else {
if (tlog != null) {
tlog.close();
tlog = null;
}
}
}
}
}
The table below shows all metrics for TransferQueue.java.




