Package com.imaginea.mongodb.services.impl

Source Code of com.imaginea.mongodb.services.impl.GridFSServiceImpl

/*
* Copyright (c) 2011 Imaginea Technologies Private Ltd.
* Hyderabad, India
*
* 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 com.imaginea.mongodb.services.impl;

import com.imaginea.mongodb.exceptions.*;
import com.imaginea.mongodb.services.AuthService;
import com.imaginea.mongodb.services.CollectionService;
import com.imaginea.mongodb.services.DatabaseService;
import com.imaginea.mongodb.services.GridFSService;
import com.imaginea.mongodb.utils.JSON;
import com.mongodb.*;
import com.mongodb.gridfs.GridFS;
import com.mongodb.gridfs.GridFSDBFile;
import com.mongodb.gridfs.GridFSInputFile;
import com.sun.jersey.core.header.FormDataContentDisposition;
import com.sun.jersey.multipart.FormDataBodyPart;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.*;

/**
* Defines services definitions for performing operations like create/drop on
* collections inside a database present in mongo to which we are connected to.
* Also provides service to get list of all collections present and Statistics
* of a particular file.
*
* @author Srinath Anantha
*/
public class GridFSServiceImpl implements GridFSService {

    /**
     * Mongo Instance to communicate with mongo
     */
    private Mongo mongoInstance;

    private DatabaseService databaseService;
    private CollectionService collectionService;

    private static final AuthService AUTH_SERVICE = AuthServiceImpl.getInstance();
    private static final String FILES_COLLECTION_FIELD_STRING = "_filesCollection";
    private static final String CHUNKS_COLLECTION_FIELD_STRING = "_chunkCollection";

    /**
     * Creates an instance of MongoInstanceProvider which is used to get a mongo
     * instance to perform operations on files. The instance is created
     * based on a userMappingKey which is received from the file request
     * dispatcher and is obtained from tokenId of user.
     *
     * @param connectionId A combination of username,mongoHost and mongoPort
     */
    public GridFSServiceImpl(String connectionId) throws ApplicationException {
        mongoInstance = AUTH_SERVICE.getMongoInstance(connectionId);
        databaseService = new DatabaseServiceImpl(connectionId);
        collectionService = new CollectionServiceImpl(connectionId);
    }

    /**
     * Service implementation for creating GridFS store in the specified database.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @return Status message.
     */
    public String createStore(String dbName, String bucketName) throws DatabaseException, CollectionException, GridFSException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Is Null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket Name Empty");
        }
        if (getAllBuckets(dbName).contains(bucketName)) {
            throw new CollectionException(ErrorCodes.COLLECTION_ALREADY_EXISTS, "Collection [" + bucketName + "] already exists in Database [" + dbName + "]");
        } else {
            try {
                new GridFS(mongoInstance.getDB(dbName), bucketName);
            } catch (MongoException e) {
                throw new GridFSException(ErrorCodes.GRIDFS_CREATION_EXCEPTION, e.getMessage());
            }
            return "GridFS bucket [" + bucketName + "] added to database [" + dbName + "].";
        }
    }

    /**
     * Service implementation for getting the list of files stored in GridFS of specified database.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @param bucketType
     * @param command
     * @param query
     * @param skip
     * @param limit
     * @param sortBy     @return JSON representation of list of all files as a String.
     */
    public JSONObject executeQuery(String dbName, String bucketName, String bucketType, String command, String query, String skip, String limit, String sortBy) throws ApplicationException, JSONException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Is Null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.BUCKET_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.BUCKET_NAME_EMPTY, "Bucket Name Empty");
        }
        if (bucketType == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection name is null");
        }
        if (bucketType.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Collection Name Empty");
        }
        if (!databaseService.getDbList().contains(dbName)) {
            throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "Database with dbName [ " + dbName + "] does not exist");
        }
        DB db = mongoInstance.getDB(dbName);
        GridFS gridFS = new GridFS(db, bucketName);
        DBCollection filesCollection = getGridFSCollection(gridFS, bucketType);
        try {
            if (command.equals("find")) {
                return executeFind(filesCollection, query, sortBy, limit, skip);
            } else if (command.equals("drop")) {
                return executeDrop(db, bucketName);
            } else {
                throw new InvalidMongoCommandException(ErrorCodes.COMMAND_NOT_SUPPORTED, "This command is not supported in GridFS");
            }
        } catch (MongoException e) {
            throw new GridFSException(ErrorCodes.QUERY_EXECUTION_EXCEPTION, e.getMessage());
        }
    }

    private JSONObject executeFind(DBCollection filesCollection, String query, String sortBy, String limit, String skip) throws JSONException {
        DBObject queryObj = (DBObject) JSON.parse(query);
        DBObject sortObj = (DBObject) JSON.parse(sortBy);
        int filesLimit = Integer.parseInt(limit);
        int filesSkip = Integer.parseInt(skip);
        // Partial Keys cant be fetched for a file
        DBCursor cursor = filesCollection.find(queryObj, null).sort(sortObj).skip(filesSkip).limit(filesLimit);

        Iterator<DBObject> it = cursor.iterator();
        ArrayList<DBObject> fileList = new ArrayList<DBObject>();
        while (it.hasNext()) {
            fileList.add(it.next());
        }
        JSONObject result = new JSONObject();
        long count = filesCollection.count(queryObj);
        result.put("documents", fileList);
        result.put("editable", true);
        result.put("count", count);
        return result;
    }

    private JSONObject executeDrop(DB db, String bucketName) throws JSONException {
        db.getCollection(bucketName + ".files").drop();
        db.getCollection(bucketName + ".chunks").drop();
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("success", true);
        return jsonObject;
    }

    private DBCollection getGridFSCollection(GridFS gridFS, String collectionName) throws ApplicationException {
        String collectionField = null;
        if (collectionName.equals("files")) {
            collectionField = FILES_COLLECTION_FIELD_STRING;
        } else if (collectionName.equals("chunks")) {
            throw new CollectionException(ErrorCodes.COMMAND_NOT_SUPPORTED, "Commands on chunks are not yet supported");
        } else {
            throw new CollectionException(ErrorCodes.COLLECTION_DOES_NOT_EXIST, "Collection does not exist for bucket");
        }
        Field field = null;
        try {
            field = GridFS.class.getDeclaredField(collectionField);
            field.setAccessible(true);
            return (DBCollection) field.get(gridFS);
        } catch (Exception e) {
            throw new ApplicationException(ErrorCodes.INVALID_ARGUMENT, e.getMessage());
        }
    }

    /**
     * Service implementation for retrieving the specified file stored in GridFS.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @param _id        ObjectId of the file to be retrieved
     * @return Requested multipartfile for viewing or download based on 'download' param.
     */
    public File getFile(String dbName, String bucketName, String _id) throws ValidationException, DatabaseException, CollectionException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Is Null");
        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }
        File tempFile = null;
        try {
            if (!databaseService.getDbList().contains(dbName)) {
                throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS,

                    "Database with dbName [ " + dbName + "] does not exist");
            }
            Object docId = JSON.parse(_id);
            BasicDBObject objectId = new BasicDBObject("_id", docId);
            GridFS gridFS = new GridFS(mongoInstance.getDB(dbName), bucketName);
            GridFSDBFile gridFSDBFile = gridFS.findOne(objectId);
            String tempDir = System.getProperty("java.io.tmpdir");
            tempFile = new File(tempDir + "/" + gridFSDBFile.getFilename());
            gridFSDBFile.writeTo(tempFile);

        } catch (MongoException m) {
            throw new CollectionException(ErrorCodes.GET_COLLECTION_LIST_EXCEPTION, m.getMessage());
        } catch (IOException e) {
            throw new CollectionException(ErrorCodes.GET_COLLECTION_LIST_EXCEPTION, e.getMessage());
        }
        return tempFile;
    }

    /**
     * Service implementation for uploading a file to GridFS.
     *
     * @param dbName       Name of Database
     * @param bucketName   Name of GridFS Bucket
     * @param formData     formDataBodyPart of the uploaded file
     * @param inputStream  inputStream of the uploaded file
     * @param connectionId ConnectionId of the connection
     * @return Success message with additional file details such as name, size,
     *         download url & deletion url as JSON Array string.
     */
    public JSONArray insertFile(String dbName, String bucketName, String connectionId, InputStream inputStream, FormDataBodyPart formData) throws ApplicationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");

        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket Name Empty");
        }

        JSONArray result = new JSONArray();
        FormDataContentDisposition fileData = formData.getFormDataContentDisposition();
        try {
            if (!databaseService.getDbList().contains(dbName)) {
                throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "DB [" + dbName + "] DOES NOT EXIST");
            }

            GridFS gridFS = new GridFS(mongoInstance.getDB(dbName), bucketName);
            GridFSInputFile fsInputFile = gridFS.createFile(inputStream, fileData.getFileName());
            fsInputFile.setContentType(formData.getMediaType().toString());
            fsInputFile.save();
            String objectId = JSON.serialize(fsInputFile.getId());
            JSONObject obj = new JSONObject();
            obj.put("name", fsInputFile.getFilename());
            obj.put("size", fsInputFile.getLength());
            obj.put("url", String.format("services/%s/%s/gridfs/getfile?id=%s&download=%s&connectionId=%s&ts=%s", dbName, bucketName, objectId, false, connectionId, new Date()));
            obj.put("delete_url", String.format("services/%s/%s/gridfs/dropfile?id=%s&connectionId=%s&ts=%s", dbName, bucketName, objectId, connectionId, new Date().getTime()));
            obj.put("delete_type", "GET");
            result.put(obj);

        } catch (MongoException e) {
            throw new CollectionException(ErrorCodes.UPLOAD_FILE_EXCEPTION, e.getMessage());
        } catch (JSONException e) {
            throw new ApplicationException(ErrorCodes.JSON_EXCEPTION, "Error creating json response obj", e.getCause());
        }
        return result;
    }

    /**
     * Service implementation for dropping a file from GridFS.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @param _id        Object id of file to be deleted
     * @return Status message.
     */
    public String deleteFile(String dbName, String bucketName, String _id) throws DatabaseException, DocumentException, CollectionException, ValidationException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");

        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket Name Empty");
        }

        String result = null;
        GridFSDBFile gridFSDBFile = null;
        try {
            if (!databaseService.getDbList().contains(dbName)) {
                throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "DB [" + dbName + "] DOES NOT EXIST");
            }
            if (_id == null) {
                throw new DocumentException(ErrorCodes.DOCUMENT_EMPTY, "File is empty");
            }

            GridFS gridFS = new GridFS(mongoInstance.getDB(dbName), bucketName);
            Object docId = JSON.parse(_id);
            BasicDBObject objectId = new BasicDBObject("_id", docId);
            gridFSDBFile = gridFS.findOne(objectId);

            if (gridFSDBFile == null) {
                throw new DocumentException(ErrorCodes.DOCUMENT_DOES_NOT_EXIST, "Document does not exist !");
            }

            gridFS.remove(objectId);

        } catch (MongoException e) {
            throw new DocumentException(ErrorCodes.DOCUMENT_DELETION_EXCEPTION, e.getMessage());
        }
        result = "File [" + gridFSDBFile.getFilename() + "] has been deleted.";
        return result;
    }

    @Override
    public Set<String> getAllBuckets(String dbName) throws DatabaseException, CollectionException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");

        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (!databaseService.getDbList().contains(dbName)) {
            throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "DB [" + dbName + "] DOES NOT EXIST");
        }

        Set<String> collList = collectionService.getCollList(dbName);
        Set<String> bucketsList = new HashSet<String>();
        for (String collection : collList) {
            int pos = collection.lastIndexOf(".files");
            if (pos > 0) {
                bucketsList.add(collection.substring(0, pos));
            }
        }
        return bucketsList;
    }

    /**
     * Service implementation for dropping all files from a GridFS bucket.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @return Status message.
     */
    public String dropBucket(String dbName, String bucketName) throws DatabaseException, DocumentException, CollectionException, ValidationException, JSONException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");

        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket Name Empty");
        }

        String result = null;
        try {
            if (!databaseService.getDbList().contains(dbName)) {
                throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "DB [" + dbName + "] DOES NOT EXIST");
            }
            executeDrop(mongoInstance.getDB(dbName), bucketName);
        } catch (MongoException e) {
            throw new DocumentException(ErrorCodes.DOCUMENT_DELETION_EXCEPTION, e.getMessage());
        }
        result = "Bucket [" + bucketName + "] has been deleted from Database [" + dbName + "].";
        return result;
    }

    /**
     * Service handler for getting count of all files in a GridFS bucket.
     *
     * @param dbName     Name of Database
     * @param bucketName Name of GridFS Bucket
     * @return Status message.
     */
    public JSONObject getCount(String dbName, String bucketName) throws DatabaseException, DocumentException, ValidationException, CollectionException {
        if (dbName == null) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database name is null");

        }
        if (dbName.equals("")) {
            throw new DatabaseException(ErrorCodes.DB_NAME_EMPTY, "Database Name Empty");
        }

        if (bucketName == null) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket name is null");
        }
        if (bucketName.equals("")) {
            throw new CollectionException(ErrorCodes.COLLECTION_NAME_EMPTY, "Bucket Name Empty");
        }

        JSONObject result = new JSONObject();
        try {
            if (!databaseService.getDbList().contains(dbName)) {
                throw new DatabaseException(ErrorCodes.DB_DOES_NOT_EXISTS, "DB [" + dbName + "] DOES NOT EXIST");
            }

            long count = mongoInstance.getDB(dbName).getCollection(bucketName + ".files").count();
            result.put("count", count);

        } catch (Exception e) {
            throw new DocumentException(ErrorCodes.GET_COLLECTION_LIST_EXCEPTION, e.getMessage());
        }
        return result;
    }
}
TOP

Related Classes of com.imaginea.mongodb.services.impl.GridFSServiceImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.