package com.orgzly.android.repos;
import android.net.Uri;
import android.util.Log;
import com.orgzly.android.BookName;
import com.orgzly.android.LocalStorage;
import com.orgzly.android.util.MiscUtils;
import com.orgzly.android.util.UriUtils;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class DirectoryRepo implements Repo {
private static final String TAG = DirectoryRepo.class.getName();
public static final String SCHEME = "file";
private File mDirectory;
private final Uri repoUri;
/**
*
* @param url repo url, in the format (file:/a/b/c)
* @param wipe should files be deleted first from directory
*/
public DirectoryRepo(String url, boolean wipe) throws IOException {
repoUri = Uri.parse(url);
mDirectory = new File(repoUri.getPath());
/* Delete entire contents of directory. */
if (wipe) {
LocalStorage.deleteRecursive(mDirectory);
}
createDir(mDirectory);
}
private void createDir(File dir) throws IOException {
if (! dir.isDirectory()) {
if (! dir.mkdirs()) {
throw new IOException("Failed creating directory " + dir);
}
}
}
@Override
public boolean requiresConnection() {
return false;
}
@Override
public Uri getUri() {
return repoUri;
}
@Override
public List<VersionedRook> getBooks() throws IOException {
List<VersionedRook> result = new ArrayList<>();
File[] files = mDirectory.listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String filename) {
return BookName.isSupportedFormatFileName(filename);
}
});
if (files != null) {
Arrays.sort(files);
for (int i = 0; i < files.length; i++) {
Uri uri = repoUri.buildUpon().appendPath(files[i].getName()).build();
result.add(new VersionedRook(
repoUri,
uri,
String.valueOf(files[i].lastModified()),
files[i].lastModified()
));
}
} else {
Log.e(TAG, "Listing files in " + mDirectory + " returned null. No storage permission?");
}
return result;
}
@Override
public VersionedRook retrieveBook(Uri uri, File destinationFile) throws IOException {
File sourceFile = new File(uri.getPath());
/* "Download" the file. */
MiscUtils.copyFile(sourceFile, destinationFile);
String rev = String.valueOf(sourceFile.lastModified());
long mtime = sourceFile.lastModified();
return new VersionedRook(repoUri, uri, rev, mtime);
}
@Override
public VersionedRook storeBook(File file, String fileName) throws IOException {
if (!file.exists()) {
throw new FileNotFoundException("File " + file + " does not exist");
}
File destinationFile = new File(mDirectory, fileName);
/* Create necessary directories. */
createDir(destinationFile.getParentFile());
String content = MiscUtils.readStringFromFile(file);
MiscUtils.writeStringToFile(content, destinationFile);
String rev = String.valueOf(destinationFile.lastModified());
long mtime = destinationFile.lastModified();
Uri uri = repoUri.buildUpon().appendPath(fileName).build();
return new VersionedRook(repoUri, uri, rev, mtime);
}
@Override
public VersionedRook renameBook(Uri fromUri, String name) throws IOException {
File fromFile = new File(fromUri.getPath());
Uri newUri = UriUtils.getUriForNewName(fromUri, name);
File toFile = new File(newUri.getPath());
if (toFile.exists()) {
throw new IOException("File " + toFile + " already exists");
}
if (! fromFile.renameTo(toFile)) {
throw new IOException("Failed renaming " + fromFile + " to " + toFile);
}
String rev = String.valueOf(toFile.lastModified());
long mtime = toFile.lastModified();
return new VersionedRook(repoUri, newUri, rev, mtime);
}
@Override
public void delete(Uri uri) throws IOException {
File file = new File(uri.getPath());
if (file.exists()) {
if (! file.delete()) {
throw new IOException("Failed deleting file " + uri.getPath());
}
}
}
public File getDirectory() {
return mDirectory;
}
@Override
public String toString() {
return repoUri.toString();
}
}