/*
* The MIT License (MIT)
*
* Copyright (c) 2014-2017 Sri Harsha Chilakapati
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.shc.silenceengine.backend.android;
import com.shc.silenceengine.core.SilenceException;
import com.shc.silenceengine.io.FilePath;
import com.shc.silenceengine.utils.functional.Promise;
import com.shc.silenceengine.utils.functional.TriCallback;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* @author Sri Harsha Chilakapati
*/
abstract class AndroidFilePath extends FilePath
{
/**
* Constructs an instance of FilePath by taking a path string, and a type.
*
* @param path The path string of the path
* @param type The type of the file, one of {@link Type#EXTERNAL} or {@link Type#RESOURCE}.
*/
AndroidFilePath(String path, Type type)
{
super(path, type);
}
public abstract InputStream getInputStream() throws IOException;
public abstract OutputStream getOutputStream(boolean append) throws IOException;
@Override
public Promise<Void> copyTo(FilePath path)
{
TriCallback<Boolean, Boolean, Boolean> function = (thisIsDirectory, pathIsDirectory, thisExists) ->
{
if (thisIsDirectory && !pathIsDirectory)
throw new SilenceException("Cannot copy a directory into a file.");
if (!thisIsDirectory && pathIsDirectory)
throw new SilenceException("Cannot copy a file into a directory.");
if (!thisExists)
throw new SilenceException("Cannot copy a non existing file.");
byte[] buffer = new byte[1024];
int length;
try (InputStream inputStream = getInputStream(); OutputStream outputStream = ((AndroidFilePath) path).getOutputStream(false))
{
while ((length = inputStream.read(buffer)) > 0)
outputStream.write(buffer, 0, length);
}
catch (IOException e)
{
SilenceException.reThrow(e);
}
};
return new Promise<>((resolve, reject) ->
this.isDirectory().then(thisIsDirectory ->
path.isDirectory().then(pathIsDirectory ->
this.exists().then(thisExists ->
{
function.invoke(thisIsDirectory, pathIsDirectory, thisExists);
resolve.invoke(null);
}, reject),
reject),
reject));
}
}