com.threewks.thundr.googleapis.cloudstorage.GoogleCloudStorageServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.threewks.thundr.googleapis.cloudstorage.GoogleCloudStorageServiceImpl.java

Source

/*
 * This file is a component of thundr, a software library from 3wks.
 * Read more: http://www.3wks.com.au/thundr
 * Copyright (C) 2013 3wks, <thundr@3wks.com.au>
 *
 * 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.threewks.thundr.googleapis.cloudstorage;

import static org.apache.commons.lang3.StringUtils.trimToNull;

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

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.EmptyContent;
import com.google.api.client.http.GenericUrl;
import com.google.api.client.http.HttpHeaders;
import com.google.api.client.http.HttpRequest;
import com.google.api.client.http.HttpRequestFactory;
import com.google.api.client.http.HttpResponse;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.threewks.thundr.exception.BaseException;

public class GoogleCloudStorageServiceImpl implements GoogleCloudStorageService {

    private static final String GOOGLE_STORAGE_URI = "https://storage.googleapis.com";

    private static class Tags {
        private static final String Contents = "Contents";
        private static final String Key = "Key";
        private static final String NextMarker = "NextMarker";
    }

    private DocumentBuilder documentBuilder;
    private HttpRequestFactory requestFactory;

    public GoogleCloudStorageServiceImpl(GoogleCredential googleCloudStorageCredential)
            throws ParserConfigurationException {
        this.documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
        this.requestFactory = new NetHttpTransport().createRequestFactory(googleCloudStorageCredential);
    }

    @Override
    public Bucket getBucket(BucketRequest bucketRequest) {

        List<String> bucketContents = new ArrayList<String>();
        InputStream stream = null;
        try {

            GenericUrl url = buildGetBucketUrl(bucketRequest);
            HttpRequest request = requestFactory.buildGetRequest(url).setThrowExceptionOnExecuteError(true);
            HttpResponse response = request.execute();

            stream = response.getContent();
            Document document = documentBuilder.parse(stream);

            List<Node> contents = findNamedChildren(document.getDocumentElement(), Tags.Contents);
            for (Node content : contents) {
                String key = trimToNull(findNamedValue(content, Tags.Key));
                bucketContents.add(key);
            }
            String nextMarker = findNamedValue(document.getDocumentElement(), Tags.NextMarker);
            return new Bucket(bucketRequest.getName(), nextMarker, bucketContents);

        } catch (Exception e) {
            throw new BaseException(e, "Error listing bucket %s", bucketRequest.getName());
        } finally {
            IOUtils.closeQuietly(stream);
        }
    }

    private GenericUrl buildGetBucketUrl(BucketRequest bucketRequest) {

        String urlString = String.format("%s/%s?", GOOGLE_STORAGE_URI, bucketRequest.getName());

        // max keys
        if (bucketRequest.getMaxKeys() > 0) {
            urlString = String.format("%smax-keys=%s&", urlString, bucketRequest.getMaxKeys());
        }

        // prefix
        if (bucketRequest.getPrefix() != null) {
            urlString = String.format("%sprefix=%s&", urlString, bucketRequest.getPrefix());
        }

        // marker
        if (bucketRequest.getMarker() != null) {
            urlString = String.format("%smarker=%s&", urlString, bucketRequest.getMarker());
        }

        // delimiter
        if (bucketRequest.getDelimiter() != null) {
            urlString = String.format("%sdelimiter=%s&", urlString, bucketRequest.getDelimiter());
        }

        return new GenericUrl(urlString);
    }

    @Override
    public void moveObject(String sourceBucket, String targetBucket, String object) {

        try {
            // copy the object to the target bucket
            String copyUri = String.format("%s/%s/%s", GOOGLE_STORAGE_URI, targetBucket, object);
            HttpRequest copyRequest = requestFactory.buildPutRequest(new GenericUrl(copyUri), new EmptyContent())
                    .setThrowExceptionOnExecuteError(true);
            copyRequest.setHeaders(
                    new HttpHeaders().set("x-goog-copy-source", String.format("%s/%s", sourceBucket, object)));
            copyRequest.execute();

            // delete the original from the source bucket
            String deleteUri = String.format("%s/%s/%s", GOOGLE_STORAGE_URI, sourceBucket, object);
            HttpRequest deleteRequest = requestFactory.buildDeleteRequest(new GenericUrl(deleteUri))
                    .setThrowExceptionOnExecuteError(true);
            deleteRequest.execute();
        } catch (Exception e) {
            throw new BaseException(e, "Error copying object %s from bucket %s to bucket %s", object, sourceBucket,
                    targetBucket);
        }
    }

    @Override
    public InputStream getObject(String bucket, String object) {
        try {
            String uri = String.format("%s/%s/%s", GOOGLE_STORAGE_URI, bucket, object);
            HttpRequest request = requestFactory.buildGetRequest(new GenericUrl(uri))
                    .setThrowExceptionOnExecuteError(true);
            HttpResponse response = request.execute();
            return response.getContent();
        } catch (Exception e) {
            throw new BaseException(e, "Error getting object %s from bucket %s", object, bucket);
        }
    }

    static List<Node> findNamedChildren(Node node, String name) {
        List<Node> children = new ArrayList<Node>();
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (name.equalsIgnoreCase(child.getNodeName())) {
                children.add(child);
            }
        }
        return children;
    }

    static String findNamedValue(Node node, String name) {
        Node child = findNamedChild(node, name);
        return child == null ? null : StringUtils.trimToEmpty(child.getTextContent());
    }

    static Node findNamedChild(Node node, String name) {
        NodeList childNodes = node.getChildNodes();
        for (int i = 0; i < childNodes.getLength(); i++) {
            Node child = childNodes.item(i);
            if (name.equalsIgnoreCase(child.getNodeName())) {
                return child;
            }
        }
        return null;
    }
}