/*
* Copyright 2016. SHENQINCI(沈钦赐)<dev@qinc.me>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ren.qinc.markdowneditors.model;
import android.support.annotation.NonNull;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import ren.qinc.markdowneditors.entity.FileBean;
import ren.qinc.markdowneditors.utils.Check;
import ren.qinc.markdowneditors.utils.FileUtils;
import ren.qinc.markdowneditors.utils.RxUtils;
import rx.Observable;
import rx.Subscriber;
/**
* Model统一数据管理
* Created by 沈钦赐 on 16/1/26.
*/
public class DataManager {
private IFileModel mFileModel;
public static DataManager getInstance() {
return DataManagerInstance.getManager();
}
private DataManager() {
mFileModel = FileModel.getInstance();
}
/**
* 读取文件
*
* @param file the file path
* @return the observable
*/
public Observable<String> readFile(@NonNull File file) {
return Observable.create(new Observable.OnSubscribe<String>() {
@Override
public void call(Subscriber<? super String> subscriber) {
if (file == null) {
subscriber.onError(new IllegalStateException("文件获取失败:路径错误"));
return;
}
if (file.isDirectory()) {
subscriber.onError(new IllegalStateException("文件获取失败:不是文件"));
return;
}
if (!file.exists()) {
subscriber.onError(new IllegalStateException("文件获取失败:文件不存在"));
return;
}
subscriber.onNext(FileUtils.readFile(file));
}
})
.compose(RxUtils.applySchedulersIoAndMainThread());
}
/**
* 保存文件
*
* @param file the file path
* @param content the content
* @return the observable
*/
public Observable<Boolean> saveFile(@NonNull File file, @NonNull String content) {
return Observable.create(new Observable.OnSubscribe<Boolean>() {
@Override
public void call(Subscriber<? super Boolean> subscriber) {
if (file == null) {
subscriber.onError(new IllegalStateException("文件保存失败:路径错误"));
return;
}
boolean b = FileUtils.writeByte(file, content);
subscriber.onNext(b);
}
}).compose(RxUtils.applySchedulersIoAndMainThread());
}
/**
* 获取文件列表,(md文件和文件夹)并转化为FileBean
* Gets file list data.
*
* @param currentFolder the current folder
* @return the file list data
*/
public Observable<List<FileBean>> getFileListData(File currentFolder, String key) {
File[] files = null;
if (Check.isEmpty(key))//默认,文件夹和文件
files = currentFolder
.listFiles(file -> file.isDirectory() ||
file.getName().endsWith(".md") ||
file.getName().endsWith(".markdown") ||
file.getName().endsWith(".mdown"));
else //搜索
files = currentFolder
.listFiles(file -> file.getName().contains(key) &&
(
file.getName().endsWith(".md") ||
file.getName().endsWith(".markdown") ||
file.getName().endsWith(".mdown")));//只显示md和文件夹
if (files == null)
return getCommonObservable();
return Observable
.from(files)
.filter(file -> file != null)
// .filter(file -> file.isDirectory() || file.getName().endsWith(".md"))
.flatMap(file -> mFileModel.getFileBeanObservable(file)
.filter(bean -> bean != null))
// .toList()
.toSortedList(this::fileSort)
.compose(RxUtils.applySchedulersIoAndMainThread());
}
/**
* 文件复制
* Copy file observable.
*
* @param beans the beans 待复制的文件或者文件夹集合
* @param targetPath the targetPath 目标目录
* @return the observable
*/
public Observable<FileBean> copyFile(List<FileBean> beans, String targetPath) {
return Observable
.from(beans)
// .flatMap(bean -> mFileModel.getFileObservable(bean))
.map(bean ->
FileUtils.copyFolder(bean.absPath, targetPath) ? bean : null
)
.map(bean -> {
if (bean == null) throw new IllegalStateException("复制失败了");
else return bean;
})
.map(bean -> {//新路径改变
if (targetPath.endsWith(File.separator)) {
bean.absPath = targetPath + bean.name;
} else {
bean.absPath = targetPath + File.separator + bean.name;
}
return bean;
})
.compose(RxUtils.applySchedulersIoAndMainThread());
}
public Observable<FileBean> cutFile(List<FileBean> beans, String target) {
return Observable
.from(beans)
// .flatMap(bean -> mFileModel.getFileObservable(bean))
.map(bean ->
FileUtils.moveFolder(bean.absPath, target) ? bean : null
)
.map(bean -> {
if (bean == null) throw new IllegalStateException("剪切失败了");
else return bean;
})
.map(bean -> {//新路径改变
if (target.endsWith(File.separator)) {
bean.absPath = target + bean.name;
} else {
bean.absPath = target + File.separator + bean.name;
}
return bean;
})
.compose(RxUtils.applySchedulersIoAndMainThread());
}
/**
* 过去一个数据空回调
* Gets common observable.
*
* @param <T> the type parameter
* @return the common observable
*/
@SuppressWarnings("unchecked")
private <T> Observable<T> getCommonObservable() {
return Observable.create(new Observable.OnSubscribe<T>() {
@Override
public void call(Subscriber<? super T> subscriber) {
subscriber.onNext((T) getNullList());
subscriber.onCompleted();
}
});
}
/**
* 获取一个空的List
* Gets null list.
*
* @param <T> the type parameter
* @return the null list
*/
@SuppressWarnings("unchecked")
private <T> T getNullList() {
return (T) new ArrayList<>();
}
/**
* 文件排序
* File sort int.
*
* @param file1 the file 1
* @param file2 the file 2
* @return the int
*/
private int fileSort(FileBean file1, FileBean file2) {
//大体按照时间排序
if ((file1.isDirectory && file2.isDirectory) || (!file1.isDirectory && !file2.isDirectory)) {
return file1.name.compareTo(file2.name);
// return -1 * file1.lastTime.compareTo(file2.lastTime);
}
//如果是文件和文件夹,则文件拍在前面
if (file1.isDirectory && !file2.isDirectory) {
return 1;
} else {
return -1;
}
}
private static class DataManagerInstance {
public static DataManager manager = new DataManager();
public static DataManager getManager() {
return manager;
}
}
}