DccUpload.java
| Index Score | ||
|---|---|---|
![]() |
![]() |
org.xnap.transfer |
![]() |
![]() |
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.transfer;
import java.awt.event.ActionEvent;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Hashtable;
import javax.swing.Action;
import org.apache.log4j.Logger;
import org.xnap.XNap;
import org.xnap.io.ThrottledOutputStream;
import org.xnap.net.NetHelper;
import org.xnap.peer.Peer;
import org.xnap.plugin.Plugin;
import org.xnap.transfer.action.AbstractStopAction;
import org.xnap.transfer.action.AbstractTransferAction;
import org.xnap.util.FiniteStateMachine;
import org.xnap.util.IllegalOperationException;
import org.xnap.util.State;
/**
* Uploads a file via the dcc protocol.
*/
public class DccUpload extends AbstractUpload {
//--- Constant(s) ---
public static final int SOCKET_TIMEOUT = 60 * 1000;
private static final Hashtable TRANSITION_TABLE;
static {
State[][] table = new State[][] {
{ State.NOT_STARTED,
State.CONNECTING, },
{ State.CONNECTING,
State.UPLOADING, State.STOPPING, State.STOPPED, },
{ State.UPLOADING,
State.SUCCEEDED, State.STOPPING, State.STOPPED, },
{ State.STOPPING,
State.SUCCEEDED, State.STOPPED }
};
TRANSITION_TABLE = FiniteStateMachine.createStateTable(table);
}
//--- Data field(s) ---
private static Logger logger = Logger.getLogger(DccDownload.class);
private File file;
private Peer peer;
private int port = 0;
private long totalBytesTransferred = 0;
private StateMachine sm = new StateMachine();
private int localPort;
private AbstractTransferAction stopAction = new StopAction();
//--- Constructor(s) ---
/**
*
* @param peer the peer thae file is downloaded from
* @param file the destination file, the downloaded data is stored here
* @param host the host to connect to
* @param port the port to connect to
*/
public DccUpload(Peer peer, File file)
{
this.peer = peer;
this.file = file;
}
//--- Method(s) ---
public long getBytesTransferred()
{
return totalBytesTransferred;
}
public Action[] getActions()
{
return new Action[] { stopAction, };
}
public File getFile()
{
return file;
}
public String getFilename()
{
return file.getName();
}
public long getFilesize()
{
return file.length();
}
public int getLocalPort()
{
return localPort;
}
public Peer getPeer()
{
return peer;
}
public Plugin getPlugin()
{
return null;
}
public String getStatus()
{
return sm.getDescription();
}
public long getTotalBytesTransferred()
{
return totalBytesTransferred;
}
public boolean isDone()
{
State s = sm.getState();
return s == State.SUCCEEDED || s == State.STOPPED;
}
public boolean isRunning()
{
State s = sm.getState();
return s == State.CONNECTING || s == State.DOWNLOADING;
}
public void start()
{
try {
setState(State.CONNECTING);
}
catch(IllegalOperationException e) {
logger.debug("unexpected exception", e);
}
}
private void setState(State newState, String description)
{
sm.setState(newState, description);
stateChanged();
}
private void setState(State newState)
{
sm.setState(newState);
stateChanged();
}
public void stop()
{
try {
setState(State.STOPPING);
}
catch(IllegalOperationException e) {
logger.debug("unexpected exception", e);
}
}
//--- Inner Class(es) ---
/**
* Starts the download offer.
*/
public class StopAction extends AbstractStopAction {
//--- Constructor(s) ---
public StopAction()
{
}
//--- Method(s) ---
public void actionPerformed(ActionEvent event)
{
DccUpload.this.stop();
}
}
private class StateMachine extends FiniteStateMachine
{
private ServerSocket serverSocket;
private UploadRunner runner;
//--- Constructor(s) ---
public StateMachine()
{
super(State.NOT_STARTED, TRANSITION_TABLE);
}
//--- Method(s) ---
protected synchronized void stateChanged(State oldState,
State newState)
{
if (newState == State.CONNECTING) {
try {
serverSocket = new ServerSocket(0);
serverSocket.setSoTimeout(SOCKET_TIMEOUT);
}
catch (IOException e) {
logger.debug("Could not open listener socket", e);
this.setState(State.STOPPED, XNap.tr("Could not open listener"));
}
localPort = serverSocket.getLocalPort();
if (localPort != 0) {
logger.debug("opened socket on :" + localPort);
runner = new UploadRunner(serverSocket);
Thread t = new Thread(runner, "DccUpload:" + getFilename());
t.start();
}
}
else if (newState == State.STOPPING) {
runner.die = true;
stopAction.setEnabledLater(false);
}
else if (newState == State.STOPPED || newState == State.SUCCEEDED) {
runner = null;
stopAction.setEnabledLater(false);
}
if (oldState == State.CONNECTING) {
try {
if (serverSocket != null) {
serverSocket.close();
}
}
catch (IOException e) {
logger.debug("Could not close listener socket", e);
}
serverSocket = null;
}
}
}
private class UploadRunner implements Runnable
{
private ServerSocket serverSocket;
private boolean die = false;
public UploadRunner(ServerSocket serverSocket)
{
this.serverSocket = serverSocket;
}
public void run()
{
Socket socket = null;
InputStream in = null;
OutputStream out = null;
try {
socket = serverSocket.accept();
socket.setSoTimeout(SOCKET_TIMEOUT);
in = new BufferedInputStream(socket.getInputStream());
out = new ThrottledOutputStream
(new BufferedOutputStream(socket.getOutputStream()));
upload(in, out);
setState(die ? State.STOPPED : State.SUCCEEDED);
}
catch (IOException e) {
logger.warn("connection failed", e);
setState(State.STOPPED, NetHelper.getErrorMessage(e));
}
finally {
try {
if (out != null) {
out.close();
}
if (in != null) {
in.close();
}
if (socket != null) {
socket.close();
}
}
catch (IOException e) {
}
}
}
public void upload(InputStream in, OutputStream out) throws IOException
{
InputStream fileIn = null;
try {
fileIn = new BufferedInputStream
(new FileInputStream(DccUpload.this.getFile()));
setState(State.UPLOADING);
byte[] inBuffer = new byte[4];
byte[] outBuffer = new byte[1024];
while (!die && totalBytesTransferred < getFilesize()) {
// compute the number of bytes to read
long toRead = getFilesize() - totalBytesTransferred;
int len = (int)Math.min(toRead, outBuffer.length);
len = fileIn.read(outBuffer, 0, len);
if (len == -1) {
break;
}
out.write(outBuffer, 0, len);
totalBytesTransferred += len;
// the receiver send us how many bytes he has received so far
in.read(inBuffer, 0, inBuffer.length);
}
}
finally {
transferStopped();
if (fileIn != null) {
try {
fileIn.close();
}
catch (IOException e) {
}
}
}
}
}
}
The table below shows all metrics for DccUpload.java.




