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

syncloud.google.docs.GDocsFolder Maven / Gradle / Ivy

The newest version!
package syncloud.google.docs;

import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponseException;
import syncloud.core.log.Logger;
import syncloud.google.docs.model.*;
import syncloud.storage.*;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

public class GDocsFolder extends IFolder {

    private static Logger logger = Logger.getLogger(GDocsFolder.class);
    private Entry entry;
    private HttpRequestFactory requestFactory;
    private NodeKey key;
    private Boolean deleted = false;
    private GDocsRetryingFileCreator retryingFileCreator;

    public GDocsFolder(NodeKey key, Entry entry, HttpRequestFactory requestFactory) {
            this.entry = entry;
            this.requestFactory = requestFactory;
            this.key = key;
            this.retryingFileCreator = new GDocsRetryingFileCreator(this);
        }


    public Entry getEntry() {
        return entry;
    }

    public HttpRequestFactory getRequestFactory() {
        return requestFactory;
    }

    GDocsRetryingFileCreator getRetryingFileCreator() {
        return retryingFileCreator;
    }

    @Override
    public NodeKey getKey() {
        return key;
    }

    @Override
    public List getFolders() throws StorageException {
        try {

            List folders = new ArrayList();
            for (DocumentListEntry docEntry : Feed.allEntries(requestFactory, DocsUrl.contents(entry.getResourceId()))) {
                folders.add(new GDocsFolder(key.child(docEntry.getTitle()), docEntry, requestFactory));
            }
            return folders;
        } catch (Exception e) {
            String message = String.format(IFolder.UNABLE_TO_GET_SUBFOLDERS, getName());
            logger.error(message, e);
            throw new StorageException(message);
        }
    }

    @Override
    public GDocsFolder createFolder(final String name) throws StorageException {

        try {
            ExponentialBackoff retrier = new ExponentialBackoff() {
                @Override
                public GDocsFolder process() throws NotReady, IOException {
                    try {
                        Entry folder = Feed.executePost(requestFactory, DocsUrl.contents(entry.getResourceId()), DocsContent.createFolderContent(name));
                        return new GDocsFolder(key.child(name), folder, requestFactory);
                    } catch (IOException e) {

                        try {
                            return findFolderRetrying(name);
                        } catch (StorageException storageException) {
                            throw new NotReady();
                        }
                    }
                }

            };

            return retrier.run();

        } catch (IOException e) {

            String message = String.format(UNABLE_TO_ADD_FOLDER(name, getName()));
            logger.error(message, e);
            throw new StorageException(message, e);
        }

    }

    private GDocsFolder findFolderRetrying(final String name) throws IOException {

        ExponentialBackoff retrier = new ExponentialBackoff() {
            @Override
            public GDocsFolder process() throws NotReady, IOException {

                logger.info("trying to find created folder by name");

                GDocsFolder folder = findFolder(name);
                if (folder != null) {
                    logger.info("created folder found by name");
                    return folder;
                }
                logger.info("not found");
                throw new NotReady();
            }
        };

        return retrier.run();
    }

    private GDocsFolder findFolder(String name) {

        try {
            for (DocumentListEntry docEntry : Feed.allEntries(requestFactory, DocsUrl.contents(entry.getResourceId()))) {
                if (docEntry.getTitle().equals(name))
                    return new GDocsFolder(key.child(name), docEntry, requestFactory);
            }

        } catch (Throwable e) {
            logger.error("unable to find folder by name: " + name, e);
        }

        return null;
    }

    @Override
    public void delete() throws StorageException {

        if (deleted) {
            logger.debug("file is marked as deleted");
            throw new StorageException(String.format(DOES_NOT_EXIST, getKey().getNativePath()));
        }

        try {
            Feed.executeDelete(requestFactory, DocsUrl.delete(entry.getResourceId(), true), entry.etag, true);
            deleted = true;
            logger.debug("set deleted flag");
        } catch (IOException e) {

            if (isNotFound(e)) {
                deleted = true;
                return;
            }

            String message = String.format(UNABLE_TO_DELETE_FOLDER( getName()));
            logger.error(message, e);
            throw new StorageException(message);
        }
    }

    private boolean isNotFound(IOException exception) {
        if (exception instanceof HttpResponseException)
            if (((HttpResponseException) exception).getResponse().getStatusCode() == 404)
                return true;
        return false;
    }

    @Override
    public IFile createFile(final String name, final InputStreamProvider inputStreamProvider, final long length) throws StorageException {

        if (length == 0)
            throw new StorageException("Empty files are not supported in Google Documents");

        try {
            return retryingFileCreator.create(inputStreamProvider, length, name);
        } catch (IOException e) {
            String message = String.format(UNABLE_TO_CREATE_FILE( name));
            logger.error(message, e);
            throw new StorageException(message, e);
        }

    }

    @Override
    public String getName() {
        return entry.getTitle();
    }

    @Override
    public List getContents() throws StorageException {
        List folders = new ArrayList();
        try {
            Iterable entries = Feed.allEntries(requestFactory, DocsUrl.contents(entry.getResourceId()));
//            List docs = feed.docs;
            for (DocumentListEntry node : entries) {
                if (node.isCollection())
                    folders.add(new GDocsFolder(key.child(node.getTitle()), node, requestFactory));
                else
                    folders.add(new GDocsFile(node, requestFactory, this));
            }
        } catch (HttpResponseException e) {
            String message = String.format(IFolder.UNABLE_TO_GET_CONTENTS, getName());
            logger.error(message);
            ErrorCode errorCode = ErrorCode.Unknown;
            if (e.getResponse().getStatusCode() == 401) {
                errorCode = ErrorCode.AuthenticationFailed;
            }
            throw new StorageException(errorCode, message);
        } catch (IOException e) {
            String message = String.format(IFolder.UNABLE_TO_GET_CONTENTS, getName());
            logger.error(message);
            throw new StorageException(ErrorCode.Unknown, message);
        }
        return folders;
    }

    public boolean equals(Object obj) {
        if (obj == null)
            return false;
        if (!(obj instanceof GDocsFolder))
            return false;

        GDocsFolder other = (GDocsFolder) obj;
        return entry.getResourceId().equals(other.entry.getResourceId());
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy