
automately.core.file.VirtualFileSystem Maven / Gradle / Ivy
package automately.core.file;
import automately.core.data.User;
import automately.core.data.comparators.FileComparator;
import automately.core.data.predicates.KeyStartsWithPredicate;
import automately.core.data.UserData;
import com.hazelcast.core.IMap;
import com.hazelcast.query.*;
import io.jcluster.core.Cluster;
import io.jsync.buffer.Buffer;
import io.jsync.json.JsonObject;
import io.jsync.utils.MimeUtils;
import io.jsync.utils.URIUtils;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.concurrent.TimeUnit;
public class VirtualFileSystem {
private static Cluster cluster = null;
private static IMap files = null;
private static IMap publicFileTokens = null;
private static VirtualFileStore fileStore = null;
// TODO Refactor hardcore
private VirtualFileSystem() {
}
protected static void initialize(Cluster cluster) {
VirtualFileSystem.cluster = cluster;
fileStore = VirtualFileService.getFileStore();
files = cluster.data().persistentMap("files");
publicFileTokens = cluster.data().persistentMap("files.public.tokens2"); // old ones without the 2
}
// BEGIN NEW STUFF
public static Buffer readFileData(VirtualFile file) {
checkInitialized();
Buffer tmpData = fileStore.readRawData(file);
if (tmpData == null) {
tmpData = new Buffer(); // We want the data to empty by default
}
return tmpData;
}
public static VirtualFile writeFileData(VirtualFile file, byte[] data) {
return writeFileData(file, new Buffer(data));
}
public static VirtualFile writeFileData(VirtualFile file, Buffer data) {
checkInitialized();
file.size = data.length();
file = putUserFile(file.userToken, file);
fileStore.writeRawData(file, data);
return file;
}
public static boolean deleteUserFile(User user, VirtualFile file) {
return deleteUserFile(user.token(), file.token());
}
public static boolean deleteUserFile(User user, String fileToken) {
return deleteUserFile(user.token(), fileToken);
}
public static boolean deleteUserFile(String userToken, VirtualFile file) {
return deleteUserFile(userToken, file.token());
}
public static boolean deleteUserFile(String userToken, String fileToken) {
checkInitialized();
if (userToken == null || userToken.isEmpty()) {
throw new NullPointerException("The user cannot be empty.");
}
if (fileToken == null || fileToken.isEmpty()) {
throw new NullPointerException("The file cannot be empty.");
}
if (files.containsKey(fileToken)) {
VirtualFile file = files.get(fileToken);
if (file.userToken.equals(userToken)) {
files.remove(fileToken);
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate temporaryFiles = e.get("fileToken").equal(fileToken);
for (String temporary : publicFileTokens.keySet(temporaryFiles)) {
publicFileTokens.remove(temporary);
}
return true;
}
}
return false;
}
public static VirtualFile putUserFile(String userToken, VirtualFile file){
return putUserFile(UserData.getUserByToken(userToken), file);
}
public static VirtualFile putUserFile(User user, VirtualFile file) {
checkInitialized();
if (user == null) {
throw new NullPointerException("The user cannot be empty.");
}
if (file == null) {
throw new NullPointerException("The file cannot be empty.");
}
if (file.name == null || file.name.isEmpty()) {
throw new RuntimeException("The file name cannot be empty.");
}
if (file.pathAlias == null || file.pathAlias.isEmpty()) {
file.pathAlias = "/";
}
/**
* Automatically get and retrieve the mime-type
*/
String fRegex = "\\.(?=[^\\\\.]+$)";
if (file.name.split(fRegex).length > 1) {
if (MimeUtils.getMimeTypeForExtension(file.name.split(fRegex)[1]) != null) {
String extension = file.name.split(fRegex)[1];
file.type = MimeUtils.getMimeTypeForExtension(extension);
}
}
if (file.type == null || file.type.isEmpty()) {
file.type = "application/octet-stream";
}
// Check both public files and such
if (containsUserFile(user, file.pathAlias + file.name)) {
VirtualFile existingFile = getUserFile(user, file.pathAlias + file.name);
if (existingFile != null) {
existingFile.name = file.name;
existingFile.pathAlias = file.pathAlias;
existingFile.type = file.type;
existingFile.isPublic = file.isPublic;
existingFile.size = file.size;
file = existingFile;
}
checkDuplicateUserFiles(file);
}
file.userToken = user.token();
file.updated = new Date();
files.set(file.token(), file);
return file;
}
public static boolean containsUserFile(User user, String fullPathOrToken) {
return containsUserFile(user, fullPathOrToken, false);
}
public static boolean containsUserFile(User user, String fullPathOrToken, boolean publicOnly) {
return getUserFiles(user, fullPathOrToken, 0, 0, false, publicOnly, true).size() > 0;
}
public static VirtualFile getUserFile(User user, String fullPathOrToken) {
return getUserFile(user, fullPathOrToken, false);
}
public static VirtualFile getUserFile(User user, String fullPathOrToken, boolean publicOnly) {
Iterator iterator = getUserFiles(user, fullPathOrToken, 0, 0, false, publicOnly, true).iterator();
if(iterator.hasNext()){
return iterator.next();
}
return null;
}
public static Collection getUserFiles(User user) {
return getUserFiles(user, null, 0, 10, false, false, true);
}
public static Collection getUserFiles(User user, String path) {
return getUserFiles(user, path, 0, 0, true, false, true);
}
public static Collection getUserFiles(User user, String path, boolean publicOnly) {
return getUserFiles(user, path, 0, 0, true, publicOnly, true);
}
public static Collection getUserFiles(User user, String path, int page, int count, boolean recursive, boolean publicOnly, boolean noPaging) {
checkInitialized();
List predicateList = new LinkedList<>();
predicateList.add(Predicates.equal("userToken", user.token()));
if(path != null && !path.isEmpty()){
String fileName = getFilename(path);
String pathAlias = getPathAlias(path);
if(!pathAlias.isEmpty()){
if(recursive){
predicateList.add(new KeyStartsWithPredicate("pathAlias", pathAlias));
} else {
predicateList.add(Predicates.equal("pathAlias", pathAlias));
}
}
if(!fileName.isEmpty()){
predicateList.add(Predicates.equal("name", fileName));
}
}
if(publicOnly){
predicateList.add(Predicates.equal("isPublic", true));
}
Predicate userFilesPredicate = Predicates.or(Predicates.and(predicateList.toArray(new Predicate[predicateList.size()])),
Predicates.and(Predicates.equal("token", path), Predicates.equal("userToken", user.token())));
if(noPaging){
return files.values(userFilesPredicate);
}
int defaultPage = 0;
if (page > -1) {
defaultPage = page;
}
if (count > 100) count = 100;
int defaultCount = 10;
// Max Count is always 100
if (count > 0) {
defaultCount = count;
}
// This predicate uses the previous one.. and then sorts the posts by date...
// IMPORTANT apparently can't lambda
PagingPredicate pagingPredicate = new PagingPredicate(userFilesPredicate, new FileComparator(), defaultCount);
Collection values = files.values(pagingPredicate);
if (defaultCount > pagingPredicate.getPage()) {
while (defaultPage > pagingPredicate.getPage()) {
pagingPredicate.nextPage();
}
values = files.values(pagingPredicate);
}
return values;
}
public static String getPathAlias(String fullPath) {
String path = fullPath;
path = path.trim();
String alias;
if (!path.endsWith("/") && Paths.get(path).getParent() != null) {
Path mPath = Paths.get(path).getParent();
alias = mPath.toString().replace("\\", "/");
} else if (path.endsWith("/")) {
Path mPath = Paths.get(path);
alias = mPath.toString().replace("\\", "/");
} else {
alias = "/";
}
if (!alias.startsWith("/")) {
alias = "/" + alias;
}
if (!alias.endsWith("/")) {
alias = alias + "/";
}
// Make sure we return sanitized
return URIUtils.removeDotSegments(alias.trim());
}
public static String getFilename(String fullPath) {
// TODO Improve this stuff
String path = fullPath;
path = URIUtils.removeDotSegments(path.trim());
if(!path.endsWith("/") && !path.equals(".")){
return Paths.get(path).getFileName().toString().trim();
}
return "";
}
private static void checkInitialized() {
if (cluster == null || files == null) {
throw new RuntimeException("VirtualFileSystem has not been initialized!");
}
}
private static void checkDuplicateUserFiles(VirtualFile file) {
// TODO Implement elsewhere
// Begin duplicate checking code.
EntryObject e = new PredicateBuilder().getEntryObject();
Predicate predicate = e.get("userToken").equal(file.userToken)
.and(e.get("name").equal(file.name))
.and(e.get("pathAlias").equal(file.pathAlias))
.and(e.get("token").notEqual(file.token()));
Collection duplicateFiles = files.values(predicate);
if (duplicateFiles.size() > 0) {
for (VirtualFile mFile : duplicateFiles) {
files.remove(mFile.token());
}
}
}
public static boolean validatePublicFileToken(VirtualFile file, String publicFileToken) {
return validatePublicFileToken(file.token(), publicFileToken);
}
public static boolean validatePublicFileToken(String fileToken, String publicFileToken) {
if (publicFileTokens.containsKey(publicFileToken)) {
Object token = publicFileTokens.get(publicFileToken);
if (token instanceof JsonObject) {
JsonObject decoded = (JsonObject) token;
if (decoded.containsField("fileToken") &&
decoded.getString("fileToken").equals(fileToken)) {
if (decoded.containsField("expires")) {
long expires = decoded.getLong("expires");
if ((new Date()).getTime() > expires) {
return true;
}
// Remove it since it is expired
publicFileTokens.remove(publicFileToken);
return false;
}
return true;
}
} else if (token instanceof VirtualFileToken) {
VirtualFileToken decoded = (VirtualFileToken) token;
if (decoded.fileToken.equals(fileToken)) {
if ((new Date()).getTime() > decoded.expires.getTime()) {
return true;
}
publicFileTokens.remove(publicFileToken);
}
}
}
return false;
}
public static void deletePublicFileToken(String publicFileToken) {
publicFileTokens.remove(publicFileToken);
}
public static String generatePublicFileToken(VirtualFile file, long expiresInMinutes) {
checkInitialized();
VirtualFileToken newToken = new VirtualFileToken();
newToken.fileToken = file.token();
newToken.userToken = file.userToken;
newToken.expires = new Date((new Date()).getTime() + TimeUnit.MINUTES.toMillis(expiresInMinutes));
publicFileTokens.set(newToken.token(), newToken);
return newToken.token();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy