Java tutorial
/* * 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; } }