/*
* Created on Aug 14, 2004
*
* This file is part of Thingamablog. ( http://thingamablog.sf.net )
*
* Copyright (c) 2004, Bob Tantlinger All Rights Reserved.
*
* 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 net.sf.thingamablog.transport;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import com.enterprisedt.net.ftp.FTPClient;
import com.enterprisedt.net.ftp.FTPConnectMode;
import com.enterprisedt.net.ftp.FTPException;
import com.enterprisedt.net.ftp.FTPMessageListener;
import com.enterprisedt.net.ftp.FTPProgressMonitor;
import com.enterprisedt.net.ftp.FTPTransferType;
/**
* Transport for publishing weblogs via FTP
*
* @author Bob Tantlinger
*/
public class FTPTransport extends RemotePublishTransport
{
private static Logger logger = Logger.getLogger("net.sf.thingamablog.transport");
private FTPClient ftp = null;
private boolean isPassiveMode;
private String failMsg = "";
private MessageListener msgListener = new MessageListener();
private List asciiTypes = new ArrayList();
public void setASCIIExtentions(List l)
{
asciiTypes = l;
}
public List getASCIIExtensions()
{
return asciiTypes;
}
/* (non-Javadoc)
* @see net.sf.thingamablog.transport.PublishTransport#connect()
*/
public boolean connect()
{
//msgListener.progress = prg;
failMsg = "";
if(isConnected)
{
failMsg = "Already connected";
return false;
}
try
{
ftp = new FTPClient();
ftp.setMessageListener(msgListener);
ftp.setRemotePort(getPort());//ftp.setControlPort(getPort());
ftp.setRemoteHost(getAddress());
if(isPassiveMode)
ftp.setConnectMode(FTPConnectMode.PASV);
else
ftp.setConnectMode(FTPConnectMode.ACTIVE);
logger.info("Connecting to FTP");
ftp.connect();
ftp.login(getUserName(), getPassword());
logger.info("Logged in to FTP");
isConnected = true;
return true;
}
catch(Exception ex)
{
failMsg = "Error logging in to " + getAddress();
failMsg += "\n" + ex.getMessage();
logger.log(Level.WARNING, failMsg, ex);
ex.printStackTrace();
}
return false;
}
/* (non-Javadoc)
* @see net.sf.thingamablog.transport.PublishTransport#publishFile(java.lang.String, java.io.File, net.sf.thingamablog.transport.TransportProgress)
*/
public boolean publishFile(String pubPath, File file, TransportProgress tp)
{
msgListener.progress = tp;
if(ftp == null)
{
failMsg = "FTP Client not initialized!";
return false;
}
if(!isConnected())
{
failMsg = "Not Connected!!!";
return false;
}
if(tp.isAborted())
{
failMsg = "Aborted";
return false;
}
if(!pubPath.endsWith("/"))
pubPath += "/"; //append a trailing slash if needed
try
{
String cwd = ftp.pwd();
if(!cwd.endsWith("/"))
cwd += "/";
if(!pubPath.equals(cwd))
{
boolean changedDir = false;
try
{
ftp.chdir(pubPath); //try to change to the pub path
changedDir = true; //changed dir OK
System.out.println("Changed to " + pubPath);
logger.info("Changed to " + pubPath);
}
catch(Exception cdEx)
{
logger.log(Level.WARNING, "Problem changing FTP dir", cdEx);
}
if(!changedDir)
{
//was unable to change dir. The dir likely does not exist
//so we'll try making the dir structure of pubPath
mkdirs(pubPath);
//ftp.chdir(pubPath);
}
}
//set up the transfer properties
if(isASCII(file))
ftp.setType(FTPTransferType.ASCII);
else
ftp.setType(FTPTransferType.BINARY);
ftp.setProgressMonitor(new MyProgressMonitor(tp));
//ftp.put(new FileInputStream(file), dest);
ftp.put(new FileInputStream(file), file.getName());
//finished = true;
return true;
}
catch(Exception ex)
{
failMsg = "Error publishing file to " + pubPath;
failMsg += "\n" + ex.getMessage();
ex.printStackTrace();
logger.log(Level.WARNING, failMsg, ex);
}
//finished = true;
return false;
}
private void mkdirs(String path) throws IOException, FTPException
{
String cwd = ftp.pwd();
while(!path.startsWith(cwd))
{
System.out.println(cwd + " " + path);
ftp.cdup();//should throw exception if can't cdup
System.out.println("CDUP!");
cwd = ftp.pwd();
}
String mkPath = path.substring(cwd.length(), path.length());
System.out.println("DIRS TO MAKE: " + mkPath);
String dirs[] = splitPath(mkPath);
for(int i = 0; i < dirs.length; i++)
{
System.out.println("mkdir " + dirs[i]);
logger.info("mkdir " + dirs[i]);
//swallow exception that results from trying to
//make a dir that already exists
try
{
ftp.mkdir(dirs[i]);
}
catch(Exception ex)
{}
//change to the new dir
//throws an exception if something went wrong
ftp.chdir(dirs[i]);
}
}
/* (non-Javadoc)
* @see net.sf.thingamablog.transport.PublishTransport#disconnect()
*/
public boolean disconnect()
{
msgListener.progress = null;
try
{
if(isConnected)
ftp.quit();
}
catch(Exception ex)
{
ex.printStackTrace();
logger.log(Level.WARNING, "Problem disconnecting from FTP", ex);
return false;
}
finally
{
System.out.println("Disconnected");
logger.info("Disconnected FTP");
isConnected = false;
if(!isSavePassword())
setPassword("");
}
return true;
}
public String getFailureReason()
{
return failMsg;
}
/**
* Indicates whether the transport uses passive mode
*
* @return true if passive mode is enabled, false otherwise
*/
public boolean isPassiveMode()
{
return isPassiveMode;
}
/**
* Sets the transport to use passive mode or active mode
*
* @param b true for passive mode, false for active mode
*/
public void setPassiveMode(boolean b)
{
isPassiveMode = b;
}
private boolean isASCII(File f)
{
String name = f.getName().toLowerCase();
for(Iterator it = asciiTypes.iterator(); it.hasNext();)
{
String ext = it.next().toString().toLowerCase();
if(name.endsWith(ext))
return true;
}
return false;
}
private class MyProgressMonitor implements FTPProgressMonitor
{
private TransportProgress progress;
private long total;
public MyProgressMonitor(TransportProgress tp)
{
progress = tp;
}
public void bytesTransferred(long count)
{
progress.bytesTransferred(count - total);
total = count;
//check if the user cancelled the upload
if(progress.isAborted())
ftp.cancelTransfer();
}
}
private class MessageListener implements FTPMessageListener
{
TransportProgress progress;
public void logCommand(String cmd)
{
logger.finer("CMD : " + cmd);
if(progress != null)
progress.logMessage("CMD : " + cmd);
}
public void logReply(String rpl)
{
logger.finer("REPLY: " + rpl);
if(progress != null)
progress.logMessage("REPLY: " + rpl);
}
}
}