All Downloads are FREE. Search and download functionalities are using the official Maven repository.

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