package com.oxxo.gallery.ftp;
import java.applet.Applet;
import java.awt.Graphics;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.oxxo.gallery.exception.MissingParamException;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
import org.apache.commons.net.io.CopyStreamEvent;
import org.apache.commons.net.io.CopyStreamListener;
/**
* This Applet is used to upload files to an FTP Server. It acts like an FTP
* client that receives the necessary parameters for the FTP server and the file
* to upload. <br/>
* Optionally it has the ability to redirect after succesfully uploaded to
* another webpage.
* The applet uses the double-buffering technique to avoid flickering when
* repainting the applet.
* <a href="http://www.realapplets.com/tutorial/DoubleBuffering.html">
* Double-buffering </a>
* @author Ignacio Marmolejo
* @version 0.0.1
*/
public class FtpUploadApplet extends Applet implements CopyStreamListener{
private String localFile = null;
private String remoteFile = null;
private String ftpDir = null;
private String ftpAddress = null;
private String ftpUsername = null;
private String ftpPassword = null;
private String redirectUrl = null;
private Logger logger = null;
private Thread uploadThread = null;
private FtpUploadThread ftpThread = null;
private boolean fileUploaded = false;
private Graphics bufferGraphics;
private Image offscreen;
private Dimension dim;
private int widthTransfered = 0;
private long totalBytesTransferred = 0;
private long fileSize = 0;
private double transferedPercentage = 0.0;
/**
* Initialization method that will be called after the applet is loaded into
* the browser.
*/
@Override
public void init() {
logger = Logger.getLogger(FtpUploadApplet.class.getName());
logger.log(Level.INFO, "init");
try {
initParameters();
} catch (MissingParamException mpe) {
logger.log(Level.SEVERE, mpe.toString());
System.exit(1);
}
dim = getSize();
offscreen = createImage(dim.width, dim.height);
bufferGraphics = offscreen.getGraphics();
ftpThread = new FtpUploadThread(localFile, remoteFile, ftpAddress,
ftpUsername, ftpPassword, ftpDir);
ftpThread.setListener(this);
uploadThread = new Thread(ftpThread);
}
/**
* Set the necessary parameters for the application that are passed as
* params in the html source
*/
private void initParameters() throws MissingParamException {
if ((localFile = getParameter("localFile")) == null) {
throw new MissingParamException("Missing the localFile param");
}
if ((remoteFile = getParameter("remoteFile")) == null) {
throw new MissingParamException("Missing the remoteFile param");
}
if ((ftpDir = getParameter("ftpDir")) == null) {
throw new MissingParamException("Missing ftpDir param");
}
if ((ftpAddress = getParameter("ftpAddress")) == null) {
throw new MissingParamException("Missing ftpAddress param");
}
if ((ftpUsername = getParameter("ftpUsername")) == null) {
throw new MissingParamException("Missing ftpUsername param");
}
if ((ftpPassword = getParameter("ftpPassword")) == null) {
throw new MissingParamException("Missing ftpPassword param");
}
if ((redirectUrl = getParameter("redirectUrl")) == null) {
// This param is optional
}
logger.log(Level.INFO, "Local File: " + localFile);
logger.log(Level.INFO, "Remote File: " + remoteFile);
logger.log(Level.INFO, "FTP Dir: " + ftpDir);
logger.log(Level.INFO, "redirect URL: " + redirectUrl);
}
/**
* Shows the percentage transfered by the thread and shows a graphic
* that updates while the butes are tranfered.<br>
* These are painted in an Image. Then the image is updated in the applet.
* This is technique called:
* <a href="http://www.realapplets.com/tutorial/DoubleBuffering.html">
* Double-buffering </a>
* @param g The graphic where we are going to paint
*/
@Override
public void paint(Graphics g) {
int posX = 0;
int posY = 0;
bufferGraphics.clearRect(0, 0, dim.width, dim.height);
bufferGraphics.drawString("Uploading file to ftp server!", posX, posY += 20);
bufferGraphics.setColor(Color.RED);
bufferGraphics.drawString("Transfered: " + (int)transferedPercentage
+ "%", posX, posY += 20);
bufferGraphics.setColor(Color.black);
bufferGraphics.fillRect(posX, posY += 20, widthTransfered, 20);
g.drawImage(offscreen, 0, 0, this);
if (fileUploaded) {
if (redirectUrl != null) {
try {
URL url = new URL(redirectUrl);
this.getAppletContext().showDocument(url);
} catch (MalformedURLException mue) {
logger.log(Level.WARNING, null, mue);
}
}
}
}
/**
* Event that updates the bytes transfered by the ftp client.
* @param totalBytesTransferred Total number of bytes transfered
* @param bytesTransferred Number of byte transfered during these event
* @param streamSize The size of the buffer being transfered
*/
public void bytesTransferred(long totalBytesTransferred, int bytesTransferred, long streamSize) {
widthTransfered = (int)((totalBytesTransferred * dim.width) / streamSize);
fileSize = streamSize;
this.totalBytesTransferred = totalBytesTransferred;
if(this.totalBytesTransferred == streamSize) {
fileUploaded = true;
}
transferedPercentage = ((double)totalBytesTransferred / (double)streamSize) * 100;
repaint();
}
public void bytesTransferred(CopyStreamEvent cse) {
}
@Override
public void start() {
logger.log(Level.INFO, "start");
uploadThread.start();
}
@Override
public void stop() {
logger.log(Level.INFO, "stop");
try {
uploadThread.join();
} catch (InterruptedException ex) {
logger.log(Level.SEVERE, null, ex);
}
}
/**
* Allow us to use Double-buffering to avoid applet to flicker
* <a href="http://www.realapplets.com/tutorial/DoubleBuffering.html">
* Double-buffering </a>
* @param g The graphic to update
*/
@Override
public void update(Graphics g) {
paint(g);
}
@Override
public void destroy() {
logger.log(Level.INFO, "destroy");
}
}