package com.xenoage.utils.android.io;
import static com.xenoage.utils.collections.CollectionUtils.alist;
import java.io.File;
import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import android.content.res.Resources;
import com.xenoage.utils.android.AndroidPlatformUtils;
import com.xenoage.utils.async.AsyncResult;
import com.xenoage.utils.io.FileFilter;
import com.xenoage.utils.io.FilesystemInput;
import com.xenoage.utils.io.InputStream;
import com.xenoage.utils.jse.io.JseFile;
import com.xenoage.utils.jse.io.JseInputStream;
/**
* Some useful input/output methods for an Android application.
*
* Currently only reading the assets of the app is supported.
*
* Use {@link AndroidPlatformUtils#io()} to get an instance of this class.
*
* @author Andreas Wenger
*/
public class AndroidIO
implements FilesystemInput {
private Resources res;
/**
* Initializes the {@link AndroidIO} with the given {@link Resources}.
*/
public AndroidIO(Resources res) {
this.res = res;
}
@Override public void existsFileAsync(String filePath, AsyncResult<Boolean> exists) {
exists.onSuccess(existsFile(filePath));
}
/**
* Like {@link #existsFileAsync(String, AsyncResult)}, but with direct return.
*/
public boolean existsFile(String filepath) {
try {
java.io.InputStream is = res.getAssets().open(filepath);
is.close();
return true;
} catch (IOException ex) {
return false;
}
}
@Override public void existsDirectoryAsync(String dirPath, AsyncResult<Boolean> exists) {
exists.onSuccess(existsDirectory(dirPath));
}
/**
* Like {@link #existsDirectoryAsync(String, AsyncResult)}, but with direct return.
*/
public boolean existsDirectory(String directory) {
try {
res.getAssets().list(directory);
return true;
} catch (IOException ex) {
return false;
}
}
@Override public void listFilesAsync(String dirPath, AsyncResult<List<String>> fileNames) {
try {
fileNames.onSuccess(listFiles(dirPath));
} catch (IOException ex) {
fileNames.onFailure(ex);
}
}
/**
* Like {@link #listFilesAsync(String, AsyncResult)}, but with direct return.
*/
public List<String> listFiles(String directory)
throws IOException {
return listFiles(directory, null);
}
public List<String> listFiles(String directory, FileFilter filter)
throws IOException {
Set<String> ret = new HashSet<String>();
String[] files = res.getAssets().list(directory);
for (String file : files) {
if (filter == null || filter.accept(new JseFile(new File(directory, file))))
ret.add(file);
}
return alist(ret);
}
@Override public void listFilesAsync(String dirPath, FileFilter filter,
AsyncResult<List<String>> fileNames) {
try {
fileNames.onSuccess(listFiles(dirPath, filter));
} catch (IOException ex) {
fileNames.onFailure(ex);
}
}
@Override public void openFileAsync(String filePath, AsyncResult<InputStream> inputStream) {
try {
inputStream.onSuccess(openFile(filePath));
} catch (IOException ex) {
inputStream.onFailure(ex);
}
}
/**
* Like {@link #openFileAsync(String, AsyncResult)}, but with direct return.
*/
public JseInputStream openFile(String filePath)
throws IOException {
return new JseInputStream(res.getAssets().open(filePath));
}
/**
* Not supported on Android.
*/
public void listDirectoriesAsync(String dirPath, AsyncResult<List<String>> dirNames) {
dirNames.onFailure(new IOException(
new UnsupportedOperationException("listDirectories unsupported on Android")));
}
}