com.eywa.impl.app.mongo.services.FileService.java Source code

Java tutorial

Introduction

Here is the source code for com.eywa.impl.app.mongo.services.FileService.java

Source

/*
 * EYWA.COM (Eywa Commerce)
 * This program is an integrated platform with E-Commerce and Configurator system.
 * Support: Please, contact the Author on http://www.smartfeeling.org.
 * Copyright (C) 2014  Gian Angelo Geminiani
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

/*
 * 
 */
package com.eywa.impl.app.mongo.services;

import com.eywa.impl.app.controllers.central.Activity;
import com.eywa.impl.app.controllers.central.CentralControl;
import com.eywa.impl.app.mongo.entities.File;
import com.eywa.impl.app.mongo.entities.Hub;
import com.eywa.impl.app.mongo.entities.Process;
import com.eywa.impl.app.mongo.entities.User;
import com.eywa.impl.app.server.storage.StorageManager;
import com.eywa.impl.app.server.utils.FileFormatUtils;
import com.eywa.impl.app.server.utils.HtmlUtils;
import com.eywa.impl.app.server.utils.MediaUtils;
import com.mongodb.BasicDBList;
import com.mongodb.BasicDBObject;
import com.mongodb.DB;
import com.mongodb.DBObject;
import org.json.JSONArray;
import org.json.JSONObject;
import org.ly.Smartly;
import org.ly.commons.io.FileWrapper;
import org.ly.commons.logging.Level;
import org.ly.commons.util.*;
import org.ly.packages.mongo.impl.AbstractMongoService;
import org.ly.packages.mongo.impl.MongoPage;
import org.ly.packages.mongo.impl.StandardCodedException;
import org.ly.packages.mongo.impl.util.MongoUtils;
import org.ly.proxies.DBProxy;

import java.util.*;

/**
 * @author angelo.geminiani
 */
public class FileService extends AbstractMongoService {

    // --------------------------------------------------------------------
    //               c o n s t r u c t o r
    // --------------------------------------------------------------------

    public FileService() throws Exception {
        super((DB) DBProxy.get().getDBMain(), File.COLLECTION, Smartly.getLanguages());
    }

    // --------------------------------------------------------------------
    //               p u b l i c
    // --------------------------------------------------------------------

    public int nativeUpsert(final DBObject item) throws Exception {

        return super.upsert(item);
    }

    @Override
    public int upsert(final DBObject item) throws StandardCodedException {
        // file format
        if (File.isFile(item) && !StringUtils.hasText(File.getFormat(item))) {
            File.setFormat(item, FileFormatUtils.getInstance().getFormat(File.getExtension(item)));
        }

        // description
        File.regenerateDescription(item);
        File.regenerateParallelArrayKey(item);

        //-- save hashtags --//
        HashtagService.asyncAdd(File.COLLECTION, File.getUserId(item), File.getHubId(item), File.getKeywords(item));

        return super.upsert(item);
    }

    public DBObject updateDir(final String userId, final String hubId, final String parentId, final JSONObject item)
            throws Exception {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user && !JsonWrapper.isEmpty(item)) {
            final DBObject hub = HubService.getHub(hubId);
            if (null != hub) {
                final String id = JsonWrapper.getString(item, File.ID);
                final String name = JsonWrapper.getString(item, File.NAME);
                final String ownerId = Hub.getUserId(hub);
                final boolean is_in_folder = !hubId.equalsIgnoreCase(parentId);

                if (StringUtils.hasText(name)) {
                    DBObject dir = StringUtils.hasText(id) ? get(id) : this.getDir(parentId, name);
                    if (null == dir) {
                        dir = new File();
                        File.setType(dir, File.TYPE_DIRECTORY);
                        File.setUserId(dir, userId);
                        File.setOwnerId(dir, ownerId);
                        File.setHubId(dir, hubId);
                        File.setParentId(dir, parentId);
                        File.setLength(dir, 0);
                    } else {
                        File.incRevisionId(dir, userId);
                    }

                    File.setName(dir, name);
                    File.setDescription(dir, JsonWrapper.getString(item, File.DESCRIPTION));
                    File.setResourceName(dir, name);
                    File.setDomainId(dir, Hub.getDomainId(hub));

                    this.upsert(dir);

                    if (!StringUtils.hasText(id)) {
                        // created new folder, should add to shared if parent is shared and notify users
                        CentralControl.dispatch(
                                Activity.newInstance().setType(Activity.TYPE_UPDATE).setCollection(File.COLLECTION)
                                        .setEntity(dir).putData(Activity.ATTR_USER_ID, userId)
                                        .putData(Activity.ATTR_FILE_ID, File.getId(dir))
                                        .putData(Activity.ATTR_PARENT_ID, parentId)
                                        .putData(Activity.ATTR_IS_IN_FOLDER, is_in_folder));
                        // CentralControl.fileOnUpdate(userId, File.getId(dir), parentId, is_in_folder);
                    }

                    return dir;
                }
            }
        }
        return null;
    }

    public DBObject updateFile(final String userId, final String hubId, final String parentId,
            final JSONObject item) throws Exception {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user && !JsonWrapper.isEmpty(item)) {
            final DBObject hub = HubService.getHub(hubId);
            if (null != hub) {
                final String id = JsonWrapper.getString(item, File.ID);
                final DBObject file = this.findById(id);
                if (null != file) {

                    // final FileWrapper fw = new FileWrapper(new java.io.File(JsonWrapper.getString(item, File.TARGET_ABSOLUTE_PATH)));

                    File.setName(file, JsonWrapper.getString(item, File.NAME));
                    File.setDescription(file, JsonWrapper.getString(item, File.DESCRIPTION));
                    File.setDomainId(file, Hub.getDomainId(hub));

                    this.upsert(file);
                    return file;
                }
            }
        }
        return null;
    }

    public DBObject moveTo(final String fileId, final String parentId) throws Exception {
        final DBObject resource = super.findById(fileId);
        File.setPrevHubId(resource, File.getHubId(resource)); // if moved to recyclebin
        File.setParentId(resource, parentId);
        super.upsert(resource);

        //-- updates shared folder and notify users --//
        // CentralControl.fileOnMoveTo(fileId, parentId);
        CentralControl.dispatch(Activity.newInstance().setType(Activity.TYPE_MOVE).setCollection(File.COLLECTION)
                .setEntity(resource).putData(Activity.ATTR_FILE_ID, fileId)
                .putData(Activity.ATTR_PARENT_ID, parentId));

        return resource;
    }

    public DBObject getDir(final String parentId, final String name) {
        final DBObject query = new BasicDBObject();
        query.put(File.PARENT_ID, parentId);
        query.put(File.NAME, name);
        return super.findOne(query);
    }

    public List<DBObject> getByUserId(final String userId) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = MongoUtils.queryEquals(File.USER_ID, userId);
            return super.find(query, null, 0, 0, new String[] { File.NAME }, null);
        }
        return new ArrayList<DBObject>();
    }

    public MongoPage pagedByUserId(final String userId, final int skip, final int limit) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = MongoUtils.queryEquals(File.USER_ID, userId);
            return super.paged(query, null, skip, limit, new String[] { File.NAME }, null);
        }
        return new MongoPage();
    }

    public List<DBObject> list(final String userId, final String hubId, final String parent) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = new BasicDBObject(File.HUB_ID, hubId);
            query.put(File.PARENT_ID, parent);
            return super.find(query, null, 0, 0, new String[] { File.TYPE, File.NAME }, null);
        }
        return new ArrayList<DBObject>();
    }

    public List<DBObject> getByHubAndKeywords(final String hubId, final Collection<String> keywords,
            final String[] fieldNames) {
        final DBObject query = new BasicDBObject();
        query.put(File.HUB_ID, hubId);
        MongoUtils.queryIn(query, File.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        final String[] sortAsc = new String[] { File.NAME };
        final String[] sortDes = new String[] {};

        return super.find(query, fieldNames, sortAsc, sortDes);
    }

    public MongoPage lookup(final String hubId, final int skip, final int limit,
            final Collection<String> keywords) {
        final DBObject query = new BasicDBObject();
        query.put(File.HUB_ID, hubId);
        MongoUtils.queryIn(query, File.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        final String[] fieldNames = null;
        final String[] sortAsc = new String[] { File.NAME };
        final String[] sortDes = new String[] {};

        return super.paged(query, fieldNames, skip, limit, sortAsc, sortDes);
    }

    public MongoPage lookup(final String hubId, final int skip, final int limit, final String searchText) {

        DBObject query1 = null;
        DBObject query2 = null;

        if (!StringUtils.isNULL(hubId)) {
            // lookup in current hub
            query1 = new BasicDBObject();
            MongoUtils.queryEquals(query1, File.HUB_ID, hubId, MongoUtils.CASE_INSENSITIVE);
        }

        if (!StringUtils.isNULL(searchText)) {
            if (searchText.startsWith("#")) {
                query2 = new BasicDBObject();
                query2.put(File.PARALLEL_ARRAY_KEY, searchText.substring(1));
            } else {
                query2 = new BasicDBObject();
                final BasicDBList conditions = new BasicDBList();
                conditions.add(MongoUtils.queryEquals(File.ID, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryEquals(File.OWNER_ID, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryContains(File.NAME, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(MongoUtils.queryContains(File.DESCRIPTION, searchText, MongoUtils.CASE_INSENSITIVE));
                conditions.add(
                        MongoUtils.queryEquals(File.PARALLEL_ARRAY_KEY, searchText, MongoUtils.CASE_INSENSITIVE));

                query2.put(MongoUtils.OP_OR, conditions);
            }
        }

        DBObject query = null;
        if (null != query1 && null != query2) {
            query = new BasicDBObject();
            final BasicDBList conditions = new BasicDBList();
            conditions.add(query1);
            conditions.add(query2);
            query.put(MongoUtils.OP_AND, conditions);
        } else if (null == query2) {
            query = query1;
        } else {
            query = query2;
        }

        final String[] fieldNames = null;
        final String[] sortAsc = new String[] { File.NAME };
        final String[] sortDes = new String[] {};

        return super.paged(query, fieldNames, skip, limit, sortAsc, sortDes);
    }

    /**
     * Prepare file for download creating a process
     *
     * @param stuffId   ID
     * @param userId    ID null if downloader is a contact not registered
     * @param contactId ID null id download is a registered user
     * @param files     Array of JSONObject (file) or String (fileId)
     * @return List of Processed Files
     */
    public List<DBObject> downloadRequest(final String stuffId, final String userId, final String contactId,
            final JSONArray files, final Collection<String> out_errors) throws Exception {
        final List<DBObject> result = new LinkedList<DBObject>();
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final int len = files.length();
            for (int i = 0; i < len; i++) {
                final String entityId = StringUtils.toString(files.get(i));
                final DBObject item = getEntity(entityId);
                if (null != item) {
                    if (File.isFile(item)) {
                        // file
                        result.add(processFileForDownload(userId, item));
                    } else {
                        // directory
                        result.addAll(processDirectoryForDownload(userId, item));
                        //-- remove update directory for user --//
                        // CentralControl.fileOnDownload(StringUtils.hasText(userId) ? userId : contactId, File.getId(item));
                        CentralControl.dispatch(Activity.newInstance().setType(Activity.TYPE_DOWNLOAD)
                                .setCollection(File.COLLECTION).setEntity(item)
                                .putData(Activity.ATTR_USER_ID, StringUtils.hasText(userId) ? userId : contactId)
                                .putData(Activity.ATTR_FILE_ID, File.getId(item)));
                    }
                } else {
                    out_errors.add("FileService.downloadRequest - File Entity invalid or not found in Database: "
                            + entityId);
                }
            }
            //-- notify download --//
            for (final DBObject file : result) {
                CentralControl.dispatch(
                        Activity.newInstance().setType(Activity.TYPE_DOWNLOAD).setCollection(File.COLLECTION)
                                .setEntity(file).putData(Activity.ATTR_FILE_ID, File.getId(file))
                                .putData(Activity.ATTR_USER_ID, StringUtils.hasText(userId) ? userId : contactId));
            }
        } else {
            out_errors.add(
                    "FileService.downloadRequest - Invalid User: User is not enabled or does not exists. UserId="
                            + userId);
        }
        return result;
    }

    /**
     * Request Upload for some files.
     * Server respond with an array of files placeholders that will be resend to server with
     * file data streaming
     *
     * @param userId   ID of user owner of files
     * @param hubId    ID of hub repository
     * @param parentId ID of parent directory (or hub)
     * @param files    Array of file names
     * @return Array of file place-holders on server side data storage.
     */
    public List<DBObject> uploadRequest(final String userId, final String hubId, final String parentId,
            final String fullpath, final JSONArray files) {
        final List<DBObject> result = new LinkedList<DBObject>();
        final DBObject user = UserService.getEnabled(userId);
        final DBObject hub = HubService.getHub(hubId);
        if (null != user && null != hub) {
            final int len = files.length();
            for (int i = 0; i < len; i++) {
                final Object item = files.get(i);
                if (StringUtils.isJSONObject(item)) {
                    final FileWrapper fw = new FileWrapper(item.toString());
                    final DBObject file = this.create(user, hub, parentId, fw);
                    if (null != file) {
                        result.add(file);
                        //-- creates process --//
                        try {
                            final DBObject process = ProcessService.create(Process.TYPE_UPLOAD, userId,
                                    File.getId(file), 0);
                            File.setProcessId(file, null != process ? Process.getId(process) : "");
                        } catch (Throwable t) {
                            super.getLogger().log(Level.SEVERE, null, t);
                        }
                    }
                }
            }
        }
        return result;
    }

    public DBObject create(final String userId, final String hubId, final String parentId, final FileWrapper fw) {
        final DBObject user = UserService.getEnabled(userId);
        final DBObject hub = HubService.getHub(hubId);
        return create(user, hub, parentId, fw);
    }

    public DBObject create(final DBObject user, final DBObject hub, final String parentId, final FileWrapper fw) {
        if (null != user && null != hub && fw.isValid()) {
            try {
                return this.updateOrCreateFileEntity(User.getId(user), parentId, hub, fw);
            } catch (Throwable t) {
                super.getLogger().log(Level.SEVERE, null, t);
            }
        }
        return null;
    }

    public List<DBObject> getByHubId(final String userId, final String hubId, final String[] fieldsNames) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = MongoUtils.queryEquals(File.HUB_ID, hubId);
            return super.find(query, fieldsNames, -1, -1, new String[] { File.NAME }, null);
        }
        return new ArrayList<DBObject>();
    }

    public MongoPage pagedByHubId(final String userId, final String hubId, final int skip, final int limit) {
        final DBObject user = UserService.getEnabled(userId);
        if (null != user) {
            final DBObject query = MongoUtils.queryEquals(File.HUB_ID, hubId);
            return super.paged(query, null, skip, limit, new String[] { File.NAME }, null);
        }
        return new MongoPage();
    }

    public int countFilesByUser(final String userId) {
        return this.countAllByUserId(userId);
    }

    public int countFilesByHub(final String hubId, final String type) {
        return this.countAllByHubId(hubId, type);
    }

    public int countByHubAndKeywords(final String hubId, final Collection<String> keywords) {
        return this.countAllByHubIdAndKeywords(hubId, keywords);
    }

    public DBObject lookUp(final String hubId, final String parentId, final String resourceName) {
        final DBObject query = new BasicDBObject();
        query.put(File.HUB_ID, hubId);
        query.put(File.PARENT_ID, parentId);
        query.put(File.RESOURCE_NAME, resourceName);
        return super.findOne(query);
    }

    // --------------------------------------------------------------------
    //               p r i v a t e
    // --------------------------------------------------------------------

    private List<DBObject> processDirectoryForDownload(final String userId, final DBObject file) {
        final List<DBObject> result = new LinkedList<DBObject>();
        try {
            final List<DBObject> children = listFiles(File.getId(file), true, // files
                    false, // folders
                    true); // deep
            for (final DBObject child : children) {
                result.add(processFileForDownload(userId, child));
            }
        } catch (Throwable ignored) {
        }
        return result;
    }

    private DBObject processFileForDownload(final String userId, final DBObject file) {
        //-- creates process --//
        final DBObject process = ProcessService.create(Process.TYPE_DOWNLOAD, userId, File.getId(file), 0);

        //-- append processId to file --//
        File.setProcessId(file, null != process ? Process.getId(process) : "");

        return file;
    }

    private List<DBObject> getAllByUserId(final String userId) {
        final DBObject query = MongoUtils.queryEquals(File.USER_ID, userId);
        return super.find(query, null, 0, 0, new String[] { File.NAME }, null);
    }

    private int countAllByUserId(final String userId) {
        final DBObject query = MongoUtils.queryEquals(File.USER_ID, userId);
        return super.count(query);
    }

    private int countAllByHubId(final String hubId, final String type) {
        final DBObject query = MongoUtils.queryEquals(File.HUB_ID, hubId);
        if (StringUtils.hasText(type)) {
            query.put(File.TYPE, type);
        }
        return super.count(query);
    }

    private int countAllByHubIdAndKeywords(final String hubId, final Collection<String> keywords) {
        final DBObject query = new BasicDBObject();
        query.put(File.HUB_ID, hubId);
        MongoUtils.queryIn(query, File.PARALLEL_ARRAY_KEY, keywords.toArray(new String[keywords.size()]));

        return super.count(query);
    }

    private long getLengthByHub(final String hubId) throws Exception {
        long length = 0;

        final DBObject match = new BasicDBObject();
        match.put(File.HUB_ID, hubId);
        match.put(File.TYPE, File.TYPE_FILE);
        final List<DBObject> items = super.find(match, new String[] { File.LENGTH }, null, null);
        for (final DBObject item : items) {
            length += File.getLength(item);
        }
        return length;
    }

    private DBObject updateOrCreateFileEntity(final String userId, final String parentId, final DBObject hub,
            final FileWrapper file) throws StandardCodedException {
        DBObject result;
        final String hubOwnerId = Hub.getUserId(hub);
        final String hubId = Hub.getId(hub);
        // validate image name ('image' is forbidden and transformed in random name)
        checkName(file);
        final String resourceName = file.getFullName();
        final HtmlUtils.HtmlText html = HtmlUtils.toHtml(file.getDescription());

        result = this.lookUp(hubId, parentId, resourceName);
        final boolean is_in_folder;
        if (null == result) {
            is_in_folder = !hubId.equalsIgnoreCase(parentId);
            // create new
            final String fileId = File.createUUID(); //file.getHash()
            result = new File();
            File.setId(result, fileId);
            File.setLength(result, file.getLength());
            File.setUserId(result, userId); // uploader
            File.setOwnerId(result, hubOwnerId); // owner
            File.setRevisionUser(result, userId); // revisionary
            File.setHubId(result, hubId);
            File.setParentId(result, parentId);
            File.setType(result, file.getType());
            File.setCrc(result, file.getCRC());
            File.setName(result, file.getName());
            File.setAutoDescription(result, html.getHtml());
            File.setKeywords(result, html.getTagsList());
            File.setExtension(result, file.getExt());
            File.setFormat(result, FileFormatUtils.getInstance().getFormat(file.getExt()));
            File.setResourceName(result, resourceName);
            File.setSourceAbsolutePath(result, file.getAbsolutePath());
            // retrieve absolute path for storage
            File.setTargetAbsolutePath(result, StorageManager.newStoragePath(hubOwnerId, file));
        } else {
            is_in_folder = false;
            // requested update for file
            File.incRevisionId(result, userId);
            File.setAutoDescription(result, html.getHtml());
            File.setKeywords(result, html.getTagsList());
            File.setCrc(result, file.getCRC());
            File.setLength(result, file.getLength());
            File.setSourceAbsolutePath(result, file.getAbsolutePath());

            if (!StringUtils.hasText(File.getFormat(result))) {
                File.setFormat(result, FileFormatUtils.getInstance().getFormat(File.getExtension(result)));
            }
        }

        //-- update domain --//
        File.setDomainId(result, Hub.getDomainId(hub));

        this.upsert(result);

        // CentralControl.fileOnUpdate(userId, File.getId(result), parentId, is_in_folder);
        CentralControl.dispatch(Activity.newInstance().setType(Activity.TYPE_UPDATE).setCollection(File.COLLECTION)
                .setEntity(result).putData(Activity.ATTR_USER_ID, userId)
                .putData(Activity.ATTR_FILE_ID, File.getId(result)).putData(Activity.ATTR_PARENT_ID, parentId)
                .putData(Activity.ATTR_IS_IN_FOLDER, is_in_folder));

        return result;
    }

    private void checkName(final FileWrapper file) {
        if ("image".equalsIgnoreCase(file.getName())) {
            file.setName("image_".concat(RandomUtils.random(6, RandomUtils.CHARS_LOW_NUMBERS)));
        }
    }

    // --------------------------------------------------------------------
    //               S T A T I C    (private)
    // --------------------------------------------------------------------

    private static boolean isURI(final String thumb) {
        if (StringUtils.hasText(thumb) && thumb.length() < 255) {
            return PathUtils.isURI(thumb);
        }
        return false;
    }

    private static void listFiles(final List<DBObject> result, final String parentId, final boolean files,
            final boolean folders, final boolean deep, final String[] fieldNames) throws Exception {
        final FileService srvc = new FileService();
        final DBObject query = new BasicDBObject(File.PARENT_ID, parentId);
        final List<DBObject> children = srvc.find(query, fieldNames, new String[] { File.NAME }, null);
        // add only files and list directories
        for (final DBObject child : children) {
            if (File.isFile(child)) {
                // add file
                if (files) {
                    result.add(child);
                }
            } else if (File.isDirectory(child)) {
                if (folders) {
                    // add folder
                    result.add(child);
                }
                if (deep) {
                    // list dir
                    listFiles(result, File.getId(child), files, folders, deep, fieldNames);
                }
            } else {
                // what else?

            }
        }
    }

    // --------------------------------------------------------------------
    //               S T A T I C   (public)
    // --------------------------------------------------------------------

    public static DBObject get(final String fileId) {
        try {
            final FileService srvc = new FileService();
            return srvc.findById(fileId);
        } catch (Throwable ignored) {
        }
        return null;
    }

    public static DBObject getEntity(final String id_or_json) {
        try {
            final DBObject file;
            if (StringUtils.isJSONObject(id_or_json)) {
                file = MongoUtils.parseObject(id_or_json.toString());
            } else {
                file = FileService.get(id_or_json.toString());
            }
            return file;
        } catch (Throwable ignored) {
        }
        return null;
    }

    public static DBObject getOrCreateProductDirectory(final String userId, final String hubId,
            final String productID, final String productUID) {
        try {
            final FileService srvc = new FileService();
            final String parentId = hubId;
            final String name = productUID;
            final DBObject hub = HubService.getHub(hubId);

            if (null != hub) {
                DBObject dir = srvc.getDir(parentId, name);
                if (null == dir) {
                    dir = new File();
                    File.setId(dir, productID); // change ID !!!!
                    File.setType(dir, File.TYPE_DIRECTORY);
                    File.setUserId(dir, userId);
                    File.setOwnerId(dir, Hub.getUserId(hub));
                    File.setHubId(dir, hubId);
                    File.setParentId(dir, parentId);
                    File.setLength(dir, 0);
                    File.setName(dir, name);
                    File.addKeyword(dir, name);
                    File.addKeyword(dir, productID);

                    srvc.upsert(dir);
                }
                return dir;
            }
        } catch (Throwable ignored) {
        }
        return null;
    }

    public static DBObject updateName(final String fileId, final String name) {
        try {
            final FileService srvc = new FileService();
            final DBObject item = srvc.findById(fileId);
            if (null != item) {
                File.setName(item, name);
                srvc.nativeUpsert(item);
            }
        } catch (Throwable ignored) {
        }
        return null;
    }

    public static List<DBObject> getByIds(final Collection<String> fileIds) {
        try {
            final FileService srvc = new FileService();
            return srvc.findByIds(fileIds);
        } catch (Throwable ignored) {
        }
        return new ArrayList<DBObject>();
    }

    public static List<DBObject> getByIds(final String[] fileIds) {
        try {
            final FileService srvc = new FileService();
            return srvc.findByIds(fileIds);
        } catch (Throwable ignored) {
        }
        return new ArrayList<DBObject>();
    }

    public static Set<String> getParentsIds(final String[] fileIds) {
        final Set<String> result = new LinkedHashSet<String>();
        for (final String fileId : fileIds) {
            result.addAll(getParentsIds(fileId));
        }
        return result;
    }

    /**
     * Implode the tree and search for all file parents.
     *
     * @param fileId ID of file or directory
     * @return Set of unique directory id (only File Entities, Hub are excluded)
     */
    public static Set<String> getParentsIds(final String fileId) {
        final Set<String> result = new LinkedHashSet<String>();
        final DBObject item = get(fileId);
        final String parentId = File.getParentId(item);
        if (StringUtils.hasText(parentId)) {
            final DBObject parent = get(parentId);
            if (null != parent) {
                result.add(parentId);
                // recursive
                result.addAll(getParentsIds(parentId));
            }
        }
        return result;
    }

    /**
     * Return list of parent folders
     *
     * @param fileOrFolderId File or Folder ID
     * @param addCurrent     if start item is a directory
     * @param asc            Ascendant. Default is false=Descendant (from start item to root).
     *                       Ascendant list is ordered from root to start item.
     * @return List of directories
     */
    public static List<DBObject> getParents(final String fileOrFolderId, final boolean addCurrent,
            final boolean asc) {
        final List<DBObject> result = new LinkedList<DBObject>();
        final DBObject item = get(fileOrFolderId);
        if (null != item) {
            if (addCurrent && File.isDirectory(item)) {
                result.add(item);
            }
            final String parentId = File.getParentId(item);
            if (StringUtils.hasText(parentId)) {
                final DBObject parent = get(parentId);
                if (null != parent) {
                    result.add(parent);
                    // recursive
                    result.addAll(getParents(parentId, false, false));
                }
            }
        }
        if (asc) {
            Collections.reverse(result);
        }
        return result;
    }

    public static void updatePreview(final String fileId, final String thumb) {
        try {
            if (StringUtils.hasText(fileId)) {
                final FileService srvc = new FileService();
                final DBObject file = srvc.findById(fileId);
                if (null != file) {
                    if (StringUtils.hasText(thumb)) {
                        File.setPreview(file, thumb);
                        File.setPreviewType(file, isURI(thumb) ? File.PREVIEW_TYPE_URL : File.PREVIEW_TYPE_BASE64);
                    } else if (!StringUtils.hasText(File.getPreview(file))) {
                        File.setPreview(file, MediaUtils.NOTFOUND_IMAGE);
                        File.setPreviewType(file, File.PREVIEW_TYPE_UNDEFINED);
                    }
                    // save
                    srvc.upsert(file);
                }
            }
        } catch (Throwable ignored) {
        }
    }

    public static void updatePreview(final DBObject file, final String thumb) {
        try {
            final FileService srvc = new FileService();
            if (null != file) {
                if (StringUtils.hasText(thumb)) {
                    File.setPreview(file, thumb);
                    File.setPreviewType(file, isURI(thumb) ? File.PREVIEW_TYPE_URL : File.PREVIEW_TYPE_BASE64);
                } else if (!StringUtils.hasText(File.getPreview(file))) {
                    File.setPreview(file, MediaUtils.NOTFOUND_IMAGE);
                    File.setPreviewType(file, File.PREVIEW_TYPE_UNDEFINED);
                }
                // save
                srvc.upsert(file);
            }
        } catch (Throwable ignored) {
        }
    }

    public static DBObject moveToRecycleBin(final String userId, final String id) throws Exception {
        final FileService srvc = new FileService();
        final DBObject recycleBin = HubService.getRecycleBin(userId);
        final String recycleBinId = Hub.getId(recycleBin);

        return srvc.moveTo(id, recycleBinId);
    }

    public static List<DBObject> emptyRecycleBin(final String userId) throws Exception {
        final DBObject recycleBin = HubService.getRecycleBin(userId);
        return emptyRecycleBin(userId, recycleBin);
    }

    public static List<DBObject> emptyRecycleBin(final String userId, final DBObject recycleBin) throws Exception {
        final String recycleBinId = Hub.getId(recycleBin);
        final List<DBObject> files = listFiles(recycleBinId, true, true, false);
        for (final DBObject file : files) {
            remove(userId, file);
        }
        return files;
    }

    public static List<DBObject> removeByHubId(final String userId, final String hubId) throws Exception {
        final List<DBObject> result = new LinkedList<DBObject>();
        final FileService srvc = new FileService();
        final DBObject query = new BasicDBObject(File.HUB_ID, hubId);
        final List<DBObject> resources = srvc.find(query);
        for (final DBObject resource : resources) {
            result.addAll(remove(userId, resource));
        }
        return result;
    }

    public static List<DBObject> remove(final String userId, final String id) throws Exception {
        final DBObject resource = get(id);
        return remove(userId, resource);
    }

    public static List<DBObject> remove(final String userId, final DBObject resource) throws Exception {
        final List<DBObject> result = new LinkedList<DBObject>();
        if (null != resource) {
            final FileService srvc = new FileService();
            final String id = File.getId(resource);
            srvc.removeById(id);
            result.add(resource);

            //-- remove file from storage, remove all shared files --//
            // CentralControl.fileOnRemove(userId, resource);
            CentralControl.dispatch(Activity.newInstance().setType(Activity.TYPE_REMOVE)
                    .setCollection(File.COLLECTION).setEntity(resource).putData(Activity.ATTR_USER_ID, userId));

            //-- remove children in sub folders --//
            final List<DBObject> children = srvc.find(new BasicDBObject(File.PARENT_ID, id));
            if (!CollectionUtils.isEmpty(children)) {
                for (final DBObject child : children) {
                    result.addAll(remove(userId, child));
                }
            }
        }
        return result;
    }

    public static List<DBObject> listFiles(final String parentId, final boolean files, final boolean folders,
            final boolean deep) {
        final List<DBObject> result = new LinkedList<DBObject>();
        try {
            listFiles(result, parentId, files, folders, deep, null);
        } catch (Throwable ignored) {
        }
        return result;
    }

    public static int countByHub(final String hubId, final String type) {
        try {
            final FileService srvc = new FileService();
            return srvc.countAllByHubId(hubId, type);
        } catch (Throwable ignored) {
        }
        return 0;
    }

    public static long lengthByHub(final String hubId) {
        long result = 0;
        try {
            final FileService srvc = new FileService();
            return srvc.getLengthByHub(hubId);
        } catch (Throwable ignored) {
            System.out.println(ignored);
        }
        return result;
    }
}