package com.hdweiss.morgand.synchronizer.parser;
import android.text.TextUtils;
import com.hdweiss.morgand.data.dao.OrgFile;
import com.hdweiss.morgand.data.dao.OrgNode;
import com.hdweiss.morgand.data.dao.OrgNodeRepository;
import com.j256.ormlite.dao.RuntimeExceptionDao;
import com.j256.ormlite.stmt.Where;
import java.io.File;
import java.io.FileFilter;
import java.sql.SQLException;
import java.util.ArrayList;
public class OrgRepository {
private String path;
private OrgNodeRepository nodeDao;
private RuntimeExceptionDao<OrgFile, String> fileDao;
public OrgRepository(String path) {
if (TextUtils.isEmpty(path))
throw new IllegalArgumentException("Path can't be empty");
this.path = path;
this.nodeDao = new OrgNodeRepository();
this.fileDao = OrgFile.getDao();
}
/**
* @return List of OrgFiles that have been modified. Both file and file.node need to be updated/created.
*/
public ArrayList<OrgFile> getModifiedFiles() {
File rootFolder = new File(path);
if (rootFolder.exists() == false)
throw new IllegalArgumentException("Folder " + path + " does not exist");
if (rootFolder.canRead() == false)
throw new IllegalArgumentException("Can't parse " + path);
ArrayList<OrgFile> modifiedOrgFiles = new ArrayList<OrgFile>();
getModifiedFiles(rootFolder, null, modifiedOrgFiles);
return modifiedOrgFiles;
}
private void getModifiedFiles(File parentFile, OrgNode parent, ArrayList<OrgFile> modifiedOrgFiles) {
for (File file : parentFile.listFiles()) {
if (file.isDirectory() && file.isHidden() == false && hasOrgFiles(file)) {
OrgNode directoryNode = findOrCreateDirectoryNode(file, parent);
getModifiedFiles(file, directoryNode, modifiedOrgFiles);
} else if (file.isFile() && file.getName().endsWith(".org")) {
OrgFile orgFile = getOrCreateOrgFile(file, parent);
if (orgFile != null)
modifiedOrgFiles.add(orgFile);
}
}
}
private boolean hasOrgFiles(File file) {
if (file.listFiles() == null)
return false;
for(File subFile: file.listFiles()) {
if (file.isDirectory()) {
if (hasOrgFiles(subFile))
return true;
}
}
File[] files = file.listFiles(new FileFilter() {
@Override
public boolean accept(File file) {
return file.isFile() && file.getName().endsWith(".org");
}
});
return files.length > 0;
}
private OrgNode findOrCreateDirectoryNode(File file, OrgNode parent) {
try {
Where<OrgNode,Integer> query = nodeDao.queryBuilder().where();
if (parent != null)
query.eq(OrgNode.PARENT_FIELD_NAME, parent).and();
else
query.isNull(OrgNode.PARENT_FIELD_NAME).and();
query.eq(OrgNode.TITLE_FIELD_NAME, file.getName());
OrgNode node = query.queryForFirst();
if (node != null)
return node;
} catch (SQLException e) {
e.printStackTrace();
}
OrgNode node = new OrgNode();
node.type = OrgNode.Type.Directory;
node.parent = parent;
node.title = file.getName();
node.level = 0;
nodeDao.create(node);
return node;
}
private OrgFile getOrCreateOrgFile(File file, OrgNode parent) {
OrgFile orgFile = fileDao.queryForId(file.getAbsolutePath());
if (orgFile == null) {
orgFile = new OrgFile();
orgFile.path = file.getAbsolutePath();
} else {
if (file.lastModified() <= orgFile.lastModified)
return null;
try {
nodeDao.delete(orgFile);
} catch (SQLException e) {
e.printStackTrace();
}
}
orgFile.node = getRootNode(file, orgFile, parent);
return orgFile;
}
private OrgNode getRootNode(File file, OrgFile orgFile, OrgNode parent) {
OrgNode rootNode = new OrgNode();
rootNode.type = OrgNode.Type.File;
rootNode.title = file.getName();
rootNode.file = orgFile;
rootNode.parent = parent;
rootNode.level = 0;
return rootNode;
}
}