OpenNapUpload.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.xnap.plugin.opennap.net |
![]() |
![]() |
XNap 3 |
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 P2P framework and client.
*
* See the file 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.
*
* 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 org.xnap.plugin.opennap.net;
import java.awt.event.ActionEvent;
import java.io.*;
import java.util.*;
import javax.swing.Action;
import javax.swing.Icon;
import org.apache.log4j.Logger;
import org.xnap.XNap;
import org.xnap.peer.Peer;
import org.xnap.plugin.Plugin;
import org.xnap.plugin.opennap.OpenNapPlugin;
import org.xnap.plugin.opennap.net.msg.ExceptionListener;
import org.xnap.plugin.opennap.net.msg.MessageHandler;
import org.xnap.plugin.opennap.net.msg.MessageListener;
import org.xnap.plugin.opennap.net.msg.client.UploadAckMessage;
import org.xnap.plugin.opennap.net.msg.server.AltDownloadAckMessage;
import org.xnap.plugin.opennap.net.msg.server.ServerMessage;
import org.xnap.plugin.opennap.user.OpenNapUser;
import org.xnap.plugin.opennap.util.*;
import org.xnap.transfer.AbstractTransfer;
import org.xnap.transfer.Queueable;
import org.xnap.transfer.Segment;
import org.xnap.transfer.Upload;
import org.xnap.transfer.UploadManager;
import org.xnap.transfer.action.*;
import org.xnap.util.*;
import org.xnap.util.IllegalOperationException;
import org.xnap.util.State;
/**
*
*/
public class OpenNapUpload extends AbstractTransfer
implements ExceptionListener, MessageListener,
Queueable, Upload, SocketListener {
//--- Constant(s) ---
/**
* If the upload is not received within this timeout after the ack
* message has been sent, the upload will be cancelled. */
public static final int ACK_TIMEOUT = 1 * 60 * 1000;
/**
* If the upload request is not renewed within this interval, the
* upload will be cancelled. */
public static final int MAX_REREQUST_INTERVAL = 15 * 60 * 1000;
/**
* The state transition table.
*/
private static final Hashtable TRANSITION_TABLE;
static {
State[][] table = new State[][] {
{ State.NOT_STARTED,
State.WAITING, State.STOPPED },
{ State.WAITING,
State.CONNECTING, State.STOPPED, State.STOPPING, },
{ State.CONNECTING,
State.UPLOADING, State.STOPPED, State.STOPPING, },
{ State.UPLOADING,
State.SUCCEEDED, State.STOPPED, State.STOPPING, },
{ State.STOPPING,
State.STOPPED, }
};
TRANSITION_TABLE = FiniteStateMachine.createStateTable(table);
}
//--- Data Field(s) ---
protected static Logger logger = Logger.getLogger(OpenNapUpload.class);
private int queuePosition;
private StateMachine sm = new StateMachine();
private long bytesTransferred;
private long totalBytesTransferred;
private OpenNapServer server;
private OpenNapUser user;
private File file;
private String requestFilename;
private OpenNapUploadRunner runner;
private UploadSocket inSocket;
private long startTime;
private int priorityFactor = 1;
private long lastRequest;
private String hash;
private AbstractTransferAction startAction = new StartAction();
private AbstractTransferAction stopAction = new StopAction();
//--- Constructor(s) ---
public OpenNapUpload(OpenNapServer server, OpenNapUser user, File file,
String requestFilename)
{
this.server = server;
this.user = user;
this.file = file;
this.requestFilename = requestFilename;
startTime = System.currentTimeMillis();
lastRequest = System.currentTimeMillis();
}
//--- Methods ---
public void exceptionThrown(Exception e)
{
setState(State.STOPPED, e.getLocalizedMessage());
}
public File getFile()
{
return file;
}
/**
*
*/
public long getFilesize()
{
return file.length();
}
public Plugin getPlugin()
{
return OpenNapPlugin.getInstance();
}
/**
* @see xnap.transfer.Transfer#getActions()
*/
public Action[] getActions()
{
return new Action[] {
startAction, stopAction,
new LowerPriorityAction(), new RaisePriorityAction(),
};
}
/**
*
*/
public long getBytesTransferred()
{
return bytesTransferred;
}
public long getEnqueueTime()
{
return startTime;
}
public String getHash()
{
return hash;
}
public Icon getIcon()
{
return OpenNapPlugin.ICON_16;
}
public int getPriority()
{
return priorityFactor;
}
/**
* Returns the position in the {@link UploadManager} queue.
*/
public int getQueuePosition()
{
return queuePosition;
}
/**
* @see xnap.transfer.Transfer#getPeer()
*/
public Peer getPeer()
{
return user;
}
public Segment[] getSegments()
{
return null;
}
/**
* @see xnap.transfer.Transfer#getStatus()
*/
public String getStatus()
{
return sm.getDescription();
}
/**
* @see xnap.transfer.Transfer#getTotalBytesTransferred()
*/
public long getTotalBytesTransferred()
{
return totalBytesTransferred;
}
public boolean isDone()
{
State s = sm.getState();
return s == State.SUCCEEDED || s == State.STOPPED;
}
public boolean isRunning()
{
return sm.getState() == State.UPLOADING;
}
public void messageReceived(ServerMessage msg)
{
AltDownloadAckMessage m = (AltDownloadAckMessage)msg;
if (m.getServer() == server && m.nick.equals(user.getName())
&& m.filename.equals(requestFilename)) {
m.consume();
user.setHost(m.ip);
user.setPort(m.port);
setState(State.CONNECTING);
}
}
/**
* Invoked by {@link
* OpenNapTransferManager#received(UploadRequestMessage)}. */
void requested()
{
lastRequest = System.currentTimeMillis();
}
public void setHash(String hash)
{
this.hash = hash;
}
/**
*
*/
public void setQueuePosition(int position)
{
queuePosition = position;
stateChanged();
}
public boolean socketReceived(IncomingSocket s)
{
if (s instanceof UploadSocket) {
UploadSocket u = (UploadSocket)s;
if (getPeer().getName().equals(u.nick)
&& getRequestFilename().equals(u.requestFilename)) {
inSocket = u;
try {
setState(State.CONNECTING);
}
catch (IllegalOperationException e) {
u.close();
}
return true;
}
}
return false;
}
/**
* Inovked by OpenNapTransferManager after the instanciation.
*/
public void start()
{
UploadManager.getInstance().getQueue().add(this);
}
/**
* Starts the transfer. Invoked by TransferQueue.
*/
public boolean startTransfer()
{
synchronized (user) {
if (!user.isUploadLimitReached()) {
try {
queuePosition = 0;
if (user.isUploadDenied()) {
setState(State.STOPPED, XNap.tr("Upload denied"));
}
else if (!OpenNapFileHelper.isShared(getFile())) {
setState
(State.STOPPED,
XNap.tr("File is not shared anymore"));
}
else {
setState(State.WAITING);
}
return true;
}
catch (IllegalOperationException e) {
logger.error("unexpected state", e);
}
}
}
return false;
}
public void stop()
{
try {
setState(State.STOPPING);
}
catch (IllegalOperationException e) {
logger.warn("unexpected state", e);
}
}
synchronized void commit(int transferred)
{
bytesTransferred += transferred;
totalBytesTransferred += transferred;
}
/**
* @return the server
*/
OpenNapServer getServer()
{
return server;
}
String getRequestFilename()
{
return requestFilename;
}
void setTotalBytesTransferred(long totalBytesTransferred)
{
this.totalBytesTransferred = totalBytesTransferred;
}
void setState(State newState, String description)
{
sm.setState(newState, description);
stateChanged();
}
void setState(State newState)
{
sm.setState(newState);
stateChanged();
}
//--- Inner Class(es) ---
private class StateMachine extends FiniteStateMachine {
//--- Data Field(s) ---
private Thread runThread;
private XNapTask timeoutTask;
//--- Constructor(s) ---
public StateMachine()
{
super(State.NOT_STARTED, TRANSITION_TABLE);
timeoutTask = new TimeoutWatcherTask(MAX_REREQUST_INTERVAL);
Scheduler.run(MAX_REREQUST_INTERVAL, 60 * 1000, timeoutTask);
}
//--- Method(s) ---
protected synchronized void stateChanged(State oldState,
State newState)
{
if (oldState == State.NOT_STARTED) {
timeoutTask.cancel();
timeoutTask = null;
}
if (newState == State.WAITING) {
MessageHandler.subscribe
(AltDownloadAckMessage.TYPE, OpenNapUpload.this);
server.getListener().addSocketListener(OpenNapUpload.this);
user.getParent().uploadStarted();
UploadAckMessage msg
= new UploadAckMessage(user.getName(), requestFilename);
msg.setExceptionListener(OpenNapUpload.this);
MessageHandler.send(server, msg);
startAction.setEnabledLater(false);
timeoutTask = new StopTask();
Scheduler.run(ACK_TIMEOUT, timeoutTask);
// once an alternative download request is received
// or an incoming connect is registered, the state will
// be set to CONNECTING or set to STOPPED in case of a
// timeout
}
else if (newState == State.CONNECTING) {
runner = new OpenNapUploadRunner(OpenNapUpload.this, inSocket);
runThread
= new Thread(runner, "OpenNapUpload:" + getFilename());
runThread.start();
}
else if (newState == State.UPLOADING) {
transferStarted();
}
else if (newState == State.STOPPING) {
if (runThread != null) {
runner.stop();
runThread.interrupt();
runner = null;
runThread = null;
}
if (oldState == State.WAITING) {
this.setState(State.STOPPED);
}
}
else if (newState == State.SUCCEEDED
|| newState == State.STOPPED) {
if (oldState != State.NOT_STARTED) {
user.getParent().uploadStopped();
}
UploadManager.getInstance().getQueue().remove
(OpenNapUpload.this);
OpenNapPlugin.getTransferManager().done(OpenNapUpload.this);
stopAction.setEnabledLater(false);
}
if (oldState == State.WAITING) {
MessageHandler.unsubscribe(AltDownloadAckMessage.TYPE,
OpenNapUpload.this);
server.getListener().removeSocketListener(OpenNapUpload.this);
timeoutTask.cancel();
timeoutTask = null;
}
else if (oldState == State.UPLOADING) {
transferStopped();
}
}
}
/**
* Stops the upload if it has not been rerequested within timeout. */
private class TimeoutWatcherTask extends XNapTask {
private long timeout;
public TimeoutWatcherTask(long timeout)
{
this.timeout = timeout;
}
public void run()
{
if (System.currentTimeMillis() - lastRequest > timeout) {
try {
setState(State.STOPPED, XNap.tr("Remote timed out"));
}
catch (IllegalOperationException e) {
logger.error("unexpected state", e);
}
}
}
}
/**
* Stops the upload if ever run. */
private class StopTask extends XNapTask {
public void run()
{
try {
setState(State.STOPPED, XNap.tr("Remote timed out"));
}
catch (IllegalOperationException e) {
logger.error("unexpected state", e);
}
}
}
private class LowerPriorityAction extends AbstractLowerPriorityAction {
public void actionPerformed(ActionEvent e)
{
priorityFactor -= 1;
UploadManager.getInstance().getQueue().resort();
}
}
private class RaisePriorityAction extends AbstractRaisePriorityAction {
public void actionPerformed(ActionEvent e)
{
priorityFactor += 1;
UploadManager.getInstance().getQueue().resort();
}
}
private class StartAction extends AbstractStartAction {
public void actionPerformed(ActionEvent event)
{
try {
setState(State.WAITING);
}
catch (IllegalOperationException e) {
logger.error("unexpected state", e);
}
}
}
private class StopAction extends AbstractStopAction {
public void actionPerformed(ActionEvent event)
{
stop();
}
}
}
The table below shows all metrics for OpenNapUpload.java.




