com.cloudmine.api.CMFile.java Source code

Java tutorial

Introduction

Here is the source code for com.cloudmine.api.CMFile.java

Source

package com.cloudmine.api;

import com.cloudmine.api.exceptions.ConversionException;
import com.cloudmine.api.exceptions.CreationException;
import com.cloudmine.api.rest.CMStore;
import com.cloudmine.api.rest.Transportable;
import com.cloudmine.api.rest.JsonUtilities;
import com.cloudmine.api.rest.Savable;
import com.cloudmine.api.rest.callbacks.CMCallback;
import com.cloudmine.api.rest.callbacks.Callback;
import com.cloudmine.api.rest.response.FileCreationResponse;
import com.cloudmine.api.rest.response.ObjectModificationResponse;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.entity.BufferedHttpEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;

/**
 * A binary file that can be stored in CloudMine. Consists of a file name, content type, and the file
 * contents as bytes. <BR>
 * The transportable representation of a CMFile consists of the CMType (file) and content type (MIME type, defaults to application/octet-stream)
 * <br>Copyright CloudMine LLC. All rights reserved<br> See LICENSE file included with SDK for details.
 */
public class CMFile implements Transportable, Savable<FileCreationResponse, ObjectModificationResponse> {

    /**
     * Check whether the file is null and has any contents
     * @param file the file to check
     * @return true if the file is empty, false if the file has contents
     */
    public static boolean isEmpty(CMFile file) {
        return file == null || (file.getFileContents().length == 1 && file.getFileContents()[0] == 32);
    }

    public static final String TYPE_VALUE = "file";
    public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";
    public static final String IMAGE_PNG_CONTENT_TYPE = "image/png";
    private static final Logger LOG = LoggerFactory.getLogger(CMFile.class);

    private final String fileId;
    private final String contentType;
    private final byte[] fileContents;
    private Immutable<StoreIdentifier> storeId = new Immutable<StoreIdentifier>();

    /**
     * Instantiate a new CMFile with the given contents, name, and type
     * @param fileContents the contents of the file
     * @param fileId the name of the file; used to retrieve a stored file. If null, a unique name is generated
     * @param contentType the MIME type. If null, {@link #DEFAULT_CONTENT_TYPE} is used
     * @throws CreationException If given null fileContents
     */
    public CMFile(byte[] fileContents, String fileId, String contentType) throws CreationException {
        if (fileContents == null) {
            throw new CreationException(new NullPointerException("Cannot create a new file with null contents"));
        }
        this.fileId = fileId == null ? CMObject.generateUniqueObjectId() : fileId;
        this.contentType = contentType == null ? DEFAULT_CONTENT_TYPE : contentType;
        this.fileContents = fileContents;
    }

    /**
     * Instantiate a new CMFile with the given contents. A unique name will be generated, and the DEFAULT_CONTENT_TYPE will be used
     * @param contents the contents of the file
     * @throws CreationException If unable to read in the content stream
     */
    public CMFile(InputStream contents) throws CreationException {
        this(contents, null, null);
    }

    /**
     * Instantiate a new CMFile with the given contents, name, and type
     * @param contents the contents of the file
     * @param contentType the MIME type. If null, {@link #DEFAULT_CONTENT_TYPE} is used
     * @throws CreationException If given null contents or unable to read in contents
     */
    public CMFile(InputStream contents, String contentType) throws CreationException {
        this(contents, null, contentType);
    }

    /**
     * Instantiate a new CMFile, using the entity contents of the HttpResponse. The file will have the
     * given fileId
     * @param response received in response to a loadFile request
     * @param fileId the name of the file. If null a unique name will be generated
     * @throws CreationException if unable to read in the entity contents
     */
    public CMFile(HttpResponse response, String fileId) throws CreationException {
        this(extractInputStream(response), fileId, extractContentType(response));
    }

    /**
     * Instantiate a new CMFile with the given contents, name, and type
     * @param contents the contents of the file
     * @param fileId the name of the file; used to retrieve a stored file. If null, a unique name is generated
     * @param contentType the MIME type. If null, {@link #DEFAULT_CONTENT_TYPE} is used
     * @throws CreationException If unable to read in the content stream
     */
    public CMFile(InputStream contents, String fileId, String contentType) throws CreationException {
        this(inputStreamToByteArray(contents), fileId, contentType);

    }

    private static byte[] inputStreamToByteArray(InputStream contents) throws CreationException {
        try {
            return IOUtils.toByteArray(contents);
        } catch (IOException e) {
            LOG.error("IOException converting file contents to byte array", e);
            throw new CreationException(e);
        }
    }

    @Override
    @Deprecated
    public boolean setSaveWith(StoreIdentifier identifier) {
        return storeId.setValue(identifier);
    }

    @Override
    @Deprecated
    public boolean setSaveWith(JavaCMUser user) {
        return setSaveWith(StoreIdentifier.StoreIdentifier(user));
    }

    @Override
    @Deprecated
    public StoreIdentifier getSavedWith() {
        return storeId.value(StoreIdentifier.DEFAULT);
    }

    @Deprecated
    public ObjectLevel getSaveLevel() {
        return getSavedWith().getObjectLevel();
    }

    @Override
    @Deprecated
    public boolean isOnLevel(ObjectLevel level) {
        return getSavedWith().isLevel(level);
    }

    @Override
    @Deprecated
    public boolean isUserLevel() {
        return isOnLevel(ObjectLevel.USER);
    }

    @Override
    @Deprecated
    public boolean isApplicationLevel() {
        return isOnLevel(ObjectLevel.APPLICATION);
    }

    @Override
    public void save() throws ConversionException, CreationException {
        save(CMCallback.<FileCreationResponse>doNothing());
    }

    @Override
    /**
     * Save this File
     * @param callback a {@link com.cloudmine.api.rest.callbacks.FileCreationResponseCallback}
     */
    public void save(Callback<FileCreationResponse> callback) throws CreationException, ConversionException {
        store().saveFile(this, callback);
    }

    @Override
    public void delete() {
        delete(CMCallback.<ObjectModificationResponse>doNothing());
    }

    @Override
    public void delete(Callback<ObjectModificationResponse> callback) {
        switch (getSaveLevel()) {
        case APPLICATION:
            store().deleteApplicationFile(getFileId(), callback);
            break;
        case USER:
            store().deleteUserFile(getFileId(), callback);
            break;
        }
    }

    @Override
    public JavaCMUser getUser() {
        return getSavedWith().getUser();
    }

    private CMStore store() throws CreationException {
        return CMStore.getStore(storeId.value(StoreIdentifier.DEFAULT));
    }

    /**
     * Get the byte contents of the file
     * @return the byte contents of the file
     */
    public byte[] getFileContents() {
        return fileContents;
    }

    /**
     * Get the contents of the file as an InputStream
     * @return the contents of the file as an InputStream
     */
    public InputStream getFileContentStream() {
        return new ByteArrayInputStream(fileContents);
    }

    /**
     * The name of the file
     * @return the name of the file
     */
    public String getFileId() {
        return fileId;
    }

    @Override
    public String getObjectId() {
        return getFileId();
    }

    /**
     * The MIME type for this file
     * @return The MIME type for this file; if it was not specified, "application/octet-stream" is assumed
     */
    public String getMimeType() {
        return contentType;
    }

    /**
     * The MIME type for this file
     * @return The MIME type for this file; if it was not specified, "application/octet-stream" is assumed
     * @deprecated in favor of the more accurately named getMimeType
     */
    @Deprecated
    public String getContentType() {
        return getMimeType();
    }

    private static String extractContentType(HttpResponse response) {
        if (response == null || response.getEntity() == null || response.getEntity().getContentType() == null)
            return null;
        return response.getEntity().getContentType().getValue();
    }

    private static InputStream extractInputStream(HttpResponse response) throws CreationException {
        if (response == null || response.getEntity() == null)
            return null;
        try {
            return new BufferedHttpEntity(response.getEntity()).getContent();
        } catch (IOException e) {
            LOG.error("IOException getting response entity contents", e);
            throw new CreationException(e);
        }
    }

    @Override
    public int hashCode() {
        int hash = 1;
        hash = hash * 31 + contentType.hashCode();
        hash = hash * 31 + fileId.hashCode();
        hash = hash * 31 + Arrays.hashCode(fileContents);
        return hash;
    }

    @Override
    public final boolean equals(Object other) {
        if (other instanceof CMFile) {
            CMFile otherFile = (CMFile) other;
            return otherFile.getMimeType().equals(getMimeType()) && otherFile.getFileId().equals(getFileId())
                    && Arrays.equals(otherFile.getFileContents(), getFileContents());
        }
        return false;
    }

    @Override
    public String toString() {
        StringBuilder string = new StringBuilder();
        string.append("Key: ").append(fileId).append(" Content-Type: ").append(contentType).append(" contents: ");
        for (int i = 0; i < fileContents.length; i++) {
            string.append(fileContents[i]);
        }
        return string.toString();
    }

    @Override
    public String transportableRepresentation() throws ConversionException {
        return JsonUtilities.jsonCollection(JsonUtilities.createJsonProperty("key", fileId),
                JsonUtilities.createJsonProperty("content_type", contentType),
                JsonUtilities.createJsonProperty(JsonUtilities.TYPE_KEY, CMType.FILE.transportableRepresentation()))
                .transportableRepresentation();

    }
}