/* GanttProject is an opensource project management tool. License: GPL3 Copyright (C) 2005-2011 GanttProject Team 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ package net.sourceforge.ganttproject.export; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.text.MessageFormat; import net.sourceforge.ganttproject.GPLogger; import net.sourceforge.ganttproject.document.DocumentManager; import net.sourceforge.ganttproject.language.GanttLanguage; import org.apache.commons.net.ftp.FTP; import org.apache.commons.net.ftp.FTPClient; import org.apache.commons.net.ftp.FTPReply; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.Job; public class WebPublisher { public static class Ftp { private final FTPClient ftpClient = new FTPClient(); private boolean isLoggedIn; private boolean isConnected; public IStatus loginAndChangedir(DocumentManager.FTPOptions options) throws IOException { ftpClient.connect(options.getServerName().getValue()); int reply = ftpClient.getReplyCode(); if (!FTPReply.isPositiveCompletion(reply)) { ftpClient.disconnect(); return new Status(IStatus.ERROR, "net.sourceforge.ganttproject", GanttLanguage.getInstance().getText( "errorFTPConnection") + " Connection failed: " + ftpClient.getReplyString()); } isConnected = true; if (!ftpClient.login(options.getUserName().getValue(), options.getPassword().getValue())) { ftpClient.logout(); ftpClient.disconnect(); return new Status(IStatus.ERROR, "net.sourceforge.ganttproject", GanttLanguage.getInstance().getText( "errorFTPConnection") + " Login failed: " + ftpClient.getReplyString()); } isLoggedIn = true; ftpClient.enterLocalPassiveMode(); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { GPLogger.getLogger(WebPublisher.class).warning( "Failed to enter passive mode on FTP server=" + options.getServerName() + " Reply message:" + ftpClient.getReplyString()); ftpClient.enterLocalActiveMode(); if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) { return new Status(IStatus.ERROR, "net.sourceforge.ganttproject", GanttLanguage.getInstance().getText( "errorFTPConnection") + " Passive and active mode failed: " + ftpClient.getReplyString()); } } String dirName = options.getDirectoryName().getValue(); if (dirName == null) { dirName = ""; } if (!dirName.isEmpty() && !ftpClient.changeWorkingDirectory(dirName)) { ftpClient.logout(); ftpClient.disconnect(); return new Status(IStatus.ERROR, "net.sourceforge.ganttproject", GanttLanguage.getInstance().getText( "errorFTPConnection") + MessageFormat.format(" Change directory to {0} failed: ", dirName, ftpClient.getReplyString())); } ftpClient.setFileType(FTP.BINARY_FILE_TYPE); return Status.OK_STATUS; } IStatus put(File file) throws IOException { if (!ftpClient.storeFile(file.getName(), new BufferedInputStream(new FileInputStream(file)))) { return new Status(IStatus.ERROR, "net.sourceforge.ganttproject", "Failed to write file=" + file.getName() + " server response=" + ftpClient.getReplyString()); } return Status.OK_STATUS; } public void detach() throws IOException { if (isLoggedIn) { ftpClient.logout(); } if (isConnected) { ftpClient.disconnect(); } } } WebPublisher() { } public void run(final File[] exportFiles, final DocumentManager.FTPOptions options) { IJobManager jobManager = Job.getJobManager(); IProgressMonitor monitor = jobManager.createProgressGroup(); Job startingJob = new Job("starting") { @Override protected IStatus run(IProgressMonitor monitor) { monitor.beginTask("Publishing files on FTP", exportFiles.length); try { final Ftp ftp = new Ftp(); IStatus status = ftp.loginAndChangedir(options); if (!status.isOK()) { GPLogger.log(status.getMessage()); return status; } for (int i = 0; i < exportFiles.length; i++) { Job nextJob = createTransferJob(ftp, exportFiles[i]); nextJob.setProgressGroup(monitor, 1); nextJob.schedule(); nextJob.join(); } Job finishingJob = new Job("finishing") { @Override protected IStatus run(IProgressMonitor monitor) { monitor.done(); try { ftp.detach(); return Status.OK_STATUS; } catch (IOException e) { GPLogger.log(e); return Status.CANCEL_STATUS; } } }; finishingJob.setProgressGroup(monitor, 0); finishingJob.schedule(); finishingJob.join(); } catch (IOException e) { if (!GPLogger.log(e)) { e.printStackTrace(System.err); } } catch (InterruptedException e) { if (!GPLogger.log(e)) { e.printStackTrace(System.err); } } return Status.OK_STATUS; } }; startingJob.setProgressGroup(monitor, 0); startingJob.schedule(); } private Job createTransferJob(final Ftp ftp, final File file) { Job result = new Job("transfer file " + file.getName()) { @Override protected IStatus run(IProgressMonitor monitor) { try { IStatus ftpStatus = ftp.put(file); if (!ftpStatus.isOK()) { GPLogger.getLogger(WebPublisher.class).warning(ftpStatus.getMessage()); return ftpStatus; } monitor.worked(1); return Status.OK_STATUS; } catch (IOException e) { if (!GPLogger.log(e)) { e.printStackTrace(System.err); } return Status.CANCEL_STATUS; } finally { } } }; return result; } }