Skip to content

Commit

Permalink
code refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
andresoviedo committed Aug 4, 2018
1 parent cfcde3a commit f96cb1f
Show file tree
Hide file tree
Showing 17 changed files with 1,113 additions and 1,198 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/.settings
/.classpath
/.project
google-drive-ftp-adapter.log
4 changes: 3 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ google-drive-ftp-adapter
News
====

**Latest Release** v1.4.1 - 8 December 2017
**Latest Release** v1.5.0 - 04/08/2018
- [adapter-bundle-jre7-win32.zip](https://raw.github.com/andresoviedo/google-drive-ftp-adapter/master/build/google-drive-ftp-adapter-win32-jre7-bundle.zip)

**New features**:
Expand Down Expand Up @@ -274,6 +274,8 @@ Change Log

(f) fixed, (i) improved, (n) new feature

- v1.5.0 (04/08/2018)
- (i) Code refactoring. Decoupled components
- v1.4.1 (08/12/2017)
- (n) #17 Multiple ftp users
- v1.4.0 (02/12/2017)
Expand Down
23 changes: 12 additions & 11 deletions .../gdrive_ftp_adapter/GDriveFtpAdapter.java → ...ve_ftp_adapter/GoogleDriveFtpAdapter.java
100755 → 100644
Original file line number Diff line number Diff line change
@@ -1,47 +1,48 @@
package org.andresoviedo.apps.gdrive_ftp_adapter;

import java.io.IOException;
import java.net.Socket;
import java.util.Properties;

import org.andresoviedo.apps.gdrive_ftp_adapter.controller.Controller;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.Cache;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.GoogleDrive;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.GoogleDriveFactory;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.SQLiteCache;
import org.andresoviedo.apps.gdrive_ftp_adapter.service.FtpGdriveSynchService;
import org.andresoviedo.apps.gdrive_ftp_adapter.view.ftp.GFtpServerFactory;
import org.apache.ftpserver.FtpServerFactory;
import org.apache.ftpserver.ftplet.FtpException;
import org.apache.log4j.Logger;

public final class GDriveFtpAdapter {
import java.io.IOException;
import java.net.Socket;
import java.util.Properties;

public final class GoogleDriveFtpAdapter {

private static final Logger LOG = Logger.getLogger(GDriveFtpAdapter.class);
private static final Logger LOG = Logger.getLogger(GoogleDriveFtpAdapter.class);

private final org.apache.ftpserver.FtpServer server;
private final Cache cache;
private final GoogleDriveFactory googleDriveFactory;
private final GoogleDrive googleDrive;
private final FtpGdriveSynchService cacheUpdater;
private final Controller controller;

public GDriveFtpAdapter(Properties configuration) {
public GoogleDriveFtpAdapter(Properties configuration) {

int port = Integer.parseInt(configuration.getProperty("port", String.valueOf(1821)));
if (!available(port)) {
throw new IllegalArgumentException("Invalid argument. Port '" + port + "' already in used");
}

cache = new SQLiteCache(configuration);
googleDriveFactory = new GoogleDriveFactory(configuration);
googleDriveFactory.init();

googleDrive = new GoogleDrive(configuration);

googleDrive = new GoogleDrive(googleDriveFactory.getDrive());
cacheUpdater = new FtpGdriveSynchService(configuration, cache, googleDrive);

controller = new Controller(cache, googleDrive, cacheUpdater);

// FTP Setup
FtpServerFactory serverFactory = new GFtpServerFactory(controller, cache, configuration);

server = serverFactory.createServer();

}
Expand Down
16 changes: 8 additions & 8 deletions src/main/java/org/andresoviedo/apps/gdrive_ftp_adapter/Main.java
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package org.andresoviedo.apps.gdrive_ftp_adapter;

import org.andresoviedo.util.jar.JarUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
Expand All @@ -8,11 +13,6 @@
import java.util.Arrays;
import java.util.Properties;

import org.andresoviedo.util.jar.JarUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.apache.log4j.xml.DOMConfigurator;

// TODO: bug synching changes. First update from local storage will have
// set max change id, so database will be "updated" for wrong.

Expand All @@ -25,7 +25,7 @@ public final class Main {

private static final String JVM_PROPERTY_LOG4J_FILE_ID_PROPERTY_NAME = "log4j.fileId";

private static GDriveFtpAdapter app;
private static GoogleDriveFtpAdapter app;

public static void main(String[] args) {

Expand Down Expand Up @@ -61,7 +61,7 @@ public static void main(String[] args) {
configureLogging(configuration);

LOG.info("Creating application with configuration '" + configuration + "'");
app = new GDriveFtpAdapter(configuration);
app = new GoogleDriveFtpAdapter(configuration);

registerShutdownHook();

Expand Down Expand Up @@ -189,4 +189,4 @@ private static void configureLogging(Properties properties) {
ex.printStackTrace();
}
}
}
}
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
package org.andresoviedo.apps.gdrive_ftp_adapter.controller;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.andresoviedo.apps.gdrive_ftp_adapter.model.Cache;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.GFile;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.GoogleDrive;
import org.andresoviedo.apps.gdrive_ftp_adapter.model.GoogleDrive.GFile;
import org.andresoviedo.apps.gdrive_ftp_adapter.service.FtpGdriveSynchService;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.google.api.client.util.DateTime;
import java.io.*;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* TODO:
*
* 1- Reparar caché 2- Sincronización
*
* FTP Adapter Controller
*
* @author Andres Oviedo
*
*/
Expand Down Expand Up @@ -59,86 +51,71 @@ private ControllerRequest(Date date, int times) {

private static final Log LOG = LogFactory.getLog(Controller.class);

public static final String FILE_SEPARATOR = "/";

private final GoogleDrive googleDriveService;
private final GoogleDrive googleDrive;

private final FtpGdriveSynchService updaterService;

private final Cache cache;

// TODO: patch: retry action if we receive multiple requests in a few amount of time. This should be done in a separate component
private final Map<String, ControllerRequest> lastQueries = new LRUCache<String, ControllerRequest>(10);
private final Map<String, ControllerRequest> lastQueries = new LRUCache<>(10);

public Controller(Cache cache, GoogleDrive googleDrive, FtpGdriveSynchService updaterService) {
this.googleDriveService = googleDrive;
this.googleDrive = googleDrive;
this.updaterService = updaterService;
this.cache = cache;
}

public void init() {
}

public List<GFile> getFiles(String folderId) {

// patch
ControllerRequest lastAction = lastQueries.get("getFiles-" + folderId);
if (lastAction == null) {
lastAction = new ControllerRequest(new Date(), 0);
lastQueries.put("getFiles-" + folderId, lastAction);
}
lastAction.times++;

if (lastAction.times > 2) {
if (System.currentTimeMillis() < (lastAction.date.getTime() + 10000)) {
LOG.info("Forcing update for folder '" + folderId + "'");
updaterService.updateFolderNow(folderId);
}
lastAction.times = 0;
lastAction.date = new Date();
}
// patch
forceFolderUpdate(folderId);

return cache.getFiles(folderId);
return cache.getFiles(folderId);
}

public boolean renameFile(GFile file, String newName) {
LOG.info("Renaming file " + file.getName() + " to " + newName);
return touch(file, new GFile(newName));
/**
* In case the user requested the same folder 3 times in < 10 seconds, we force update
* @param folderId the folder to force update
*/
private void forceFolderUpdate(String folderId) {
// patch
ControllerRequest lastAction = lastQueries.get("getFiles-" + folderId);
if (lastAction == null) {
lastAction = new ControllerRequest(new Date(), 0);
lastQueries.put("getFiles-" + folderId, lastAction);
}
lastAction.times++;

if (lastAction.times > 2) {
if (System.currentTimeMillis() < (lastAction.date.getTime() + 10000)) {
LOG.info("Forcing update for folder '" + folderId + "'");
updaterService.updateFolderNow(folderId);
}
lastAction.times = 0;
lastAction.date = new Date();
}
// patch
}

public boolean renameFile(GFile gFile, String newName) {
LOG.info("Renaming file " + gFile.getName() + " to " + newName);
return touch(gFile, new GFile(newName));
}

public boolean updateLastModified(GFile fTPGFile, long time) {
LOG.info("Updating last modification date for " + fTPGFile.getName() + " to " + new Date(time));
public boolean updateLastModified(GFile gFile, long time) {
LOG.info("Updating last modified date for " + gFile.getName() + " to " + new Date(time));
GFile patch = new GFile(null);
patch.setLastModified(time);
return touch(fTPGFile, patch);
return touch(gFile, patch);
}

private boolean touch(GFile ftpFile, GFile patch) {
LOG.info("Patching file " + ftpFile.getName() + " with " + patch);
// com.google.api.services.drive.model.File googleFile =
// googleDriveService
// .getFile(ftpFile.getId());

com.google.api.services.drive.model.File googleFile = new com.google.api.services.drive.model.File();
googleFile.setId(ftpFile.getId());

// if (googleFile == null) {
// LOG.error("File '" + ftpFile.getName()
// + "' doesn't exists remotely. Impossible to rename");
// return false;
// }

if (patch.getName() == null && patch.getLastModified() <= 0) {
throw new IllegalArgumentException("Patching doesn't contain valid name nor modified date");
}
if (patch.getName() != null) {
googleFile.setTitle(patch.getName());
}
if (patch.getLastModified() > 0) {
googleFile.setModifiedDate(new DateTime(patch.getLastModified()));
}

com.google.api.services.drive.model.File googleFileUpdated = googleDriveService.touchFile(ftpFile.getId(), googleFile);
GFile googleFileUpdated = googleDrive.touchFile(ftpFile.getId(), patch.getName(), patch.getLastModified());
if (googleFileUpdated != null) {
updaterService.updateNow(googleFileUpdated);
return true;
Expand All @@ -148,64 +125,48 @@ private boolean touch(GFile ftpFile, GFile patch) {

public boolean trashFile(GFile file) {
String fileId = file.getId();
LOG.info("Deleting file " + fileId + "...");
boolean ret = googleDriveService.trashFile(fileId, 3) != null;
LOG.info("Trashing file " + file.getName() + "...");
boolean ret = googleDrive.trashFile(fileId, 3) != null;
if (ret)
cache.deleteFile(fileId);
return ret;
}

public boolean mkdir(String parentFileId, GFile fTPGFile) {
com.google.api.services.drive.model.File newDir = googleDriveService.mkdir(parentFileId, fTPGFile.getName());
boolean ret = newDir != null;
if (ret)
updaterService.updateNow(newDir.getId());
return ret;
public boolean mkdir(String parentFileId, GFile gFile) {
LOG.info("Creating directory " + gFile.getName() + "...");
final String fileId = googleDrive.mkdir(parentFileId, gFile.getName());
if (fileId != null) {
updaterService.updateNow(fileId);
return true;
}
return false;
}

// TODO: Implement offset
public InputStream createInputStream(GFile fTPGFile, long offset) {
File transferFile = googleDriveService.downloadFile(fTPGFile);
if (transferFile == null) {
throw new IllegalStateException("No se dispone de la URL de descarga");
}

try {
InputStream transferFileInputStream = FileUtils.openInputStream(transferFile);
transferFileInputStream.skip(offset);
return transferFileInputStream;
} catch (IOException ex) {
return null;
}

public InputStream createInputStream(GFile gFile) {
LOG.info("Downloading file " + gFile.getName() + "...");
return googleDrive.downloadFile(gFile);
}

public OutputStream createOutputStream(final GFile fTPGFileW, long offset) {
final GFile fTPGFile = fTPGFileW;
if (fTPGFile.isDirectory()) {
throw new IllegalArgumentException("createOutputStream en directorio?");
// TODO: Implement offset and upload without intermediate files
public OutputStream createOutputStream(final GFile gFile) {
if (gFile.isDirectory()) {
throw new IllegalArgumentException("Error. Can't upload files of type directory");
}

OutputStream transferFileOutputStream;
try {
final File transferFile = File.createTempFile("gdrive-synch-", ".upload." + fTPGFile.getName());
fTPGFile.setTransferFile(transferFile);
final File transferFile = File.createTempFile("gdrive-synch-", ".upload." + gFile.getName());
gFile.setTransferFile(transferFile);
transferFileOutputStream = new FileOutputStream(transferFile) {
@Override
public void close() throws IOException {
com.google.api.services.drive.model.File updatedGoogleFile = null;
final String updatedGoogleFile;
super.close();
try {
if (!fTPGFileW.isExists()) {
// New file
updatedGoogleFile = googleDriveService.uploadFile(fTPGFile);
} else {
// Update file
updatedGoogleFile = googleDriveService.uploadFile(fTPGFile);
}
updaterService.updateNow(updatedGoogleFile.getId());
updatedGoogleFile = googleDrive.uploadFile(gFile);
updaterService.updateNow(updatedGoogleFile);
} finally {
FileUtils.deleteQuietly(fTPGFile.getTransferFile());
FileUtils.deleteQuietly(gFile.getTransferFile());
}
}
};
Expand Down
Loading

0 comments on commit f96cb1f

Please sign in to comment.