com.google.refine.extension.gdata.GDataExtension.java Source code

Java tutorial

Introduction

Here is the source code for com.google.refine.extension.gdata.GDataExtension.java

Source

/*
 * Copyright (c) 2010, Thomas F. Morris
 *        All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice, this 
 *   list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice, 
 *   this list of conditions and the following disclaimer in the documentation 
 *   and/or other materials provided with the distribution.
 * 
 * Neither the name of Google nor the names of its contributors may be used to 
 * endorse or promote products derived from this software without specific 
 * prior written permission.
 * 
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */
package com.google.refine.extension.gdata;

import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Arrays;

import javax.servlet.http.HttpServletRequest;

import com.google.api.client.auth.oauth2.AuthorizationCodeResponseUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeRequestUrl;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeTokenRequest;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.googleapis.auth.oauth2.GoogleTokenResponse;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.drive.Drive;
import com.google.gdata.client.docs.DocsService;
import com.google.gdata.client.spreadsheet.SpreadsheetService;

import com.google.refine.util.ParsingUtilities;

import edu.mit.simile.butterfly.ButterflyModule;

/**
 * @author Tom Morris <tfmorris@gmail.com>
 * @copyright 2010 Thomas F. Morris
 * @license New BSD http://www.opensource.org/licenses/bsd-license.php
 */
abstract public class GDataExtension {
    static final String SERVICE_APP_NAME = "OpenRefine-GData-Extension";
    static final String CLIENT_ID = "647865400439.apps.googleusercontent.com";
    static final String CLIENT_SECRET = "0mW9OJji1yrgJk5AjJc5Pn6I"; // not really that secret, but the protocol accounts for that

    /** Global instance of the HTTP transport. */
    static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();

    /** Global instance of the JSON factory. */
    static final JsonFactory JSON_FACTORY = new JacksonFactory();

    static public String getAuthorizationUrl(ButterflyModule module, HttpServletRequest request)
            throws MalformedURLException {
        String authorizedUrl = makeRedirectUrl(module, request);

        // New Oauth2
        GoogleAuthorizationCodeRequestUrl url = new GoogleAuthorizationCodeRequestUrl(CLIENT_ID, authorizedUrl, // execution continues at authorized on redirect
                Arrays.asList("https://www.googleapis.com/auth/fusiontables",
                        "https://www.googleapis.com/auth/drive", // create new spreadsheets
                        "https://spreadsheets.google.com/feeds"));

        return url.toString();

    }

    private static String makeRedirectUrl(ButterflyModule module, HttpServletRequest request)
            throws MalformedURLException {
        StringBuffer sb = new StringBuffer(module.getMountPoint().getMountPoint());
        sb.append("authorized?winname=");
        sb.append(ParsingUtilities.encode(request.getParameter("winname")));
        sb.append("&cb=");
        sb.append(ParsingUtilities.encode(request.getParameter("cb")));

        URL thisUrl = new URL(request.getRequestURL().toString());
        URL authorizedUrl = new URL(thisUrl, sb.toString());
        return authorizedUrl.toExternalForm();
    }

    static public String getTokenFromCode(ButterflyModule module, HttpServletRequest request)
            throws MalformedURLException {
        String redirectUrl = makeRedirectUrl(module, request);
        StringBuffer fullUrlBuf = request.getRequestURL();
        if (request.getQueryString() != null) {
            fullUrlBuf.append('?').append(request.getQueryString());
        }
        AuthorizationCodeResponseUrl authResponse = new AuthorizationCodeResponseUrl(fullUrlBuf.toString());
        // check for user-denied error
        if (authResponse.getError() != null) {
            // authorization denied...
        } else {
            // request access token using authResponse.getCode()...
            String code = authResponse.getCode();
            try {
                GoogleTokenResponse response = new GoogleAuthorizationCodeTokenRequest(HTTP_TRANSPORT, JSON_FACTORY,
                        CLIENT_ID, CLIENT_SECRET, code, redirectUrl).execute();
                String token = response.getAccessToken();
                return token;
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return null;
    }

    static public DocsService getDocsService(String token) {
        DocsService service = new DocsService(SERVICE_APP_NAME);
        if (token != null) {
            service.setAuthSubToken(token);
        }
        return service;
    }

    static public SpreadsheetService getSpreadsheetService(String token) {
        SpreadsheetService service = new SpreadsheetService(SERVICE_APP_NAME);
        if (token != null) {
            service.setAuthSubToken(token);
        }
        return service;
    }

    static public Drive getDriveService(String token) {
        GoogleCredential credential = new GoogleCredential().setAccessToken(token);
        return new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, credential).setApplicationName(SERVICE_APP_NAME)
                .build();
    }

    static boolean isSpreadsheetURL(String url) {
        // e.g. http://spreadsheets.google.com/ccc?key=tI36b9Fxk1lFBS83iR_3XQA&hl=en
        // TODO: The following should work, but the GData implementation is too limited
        //        try {
        //            FeedURLFactory.getSpreadsheetKeyFromUrl(url);
        //            return true;
        //        } catch (IllegalArgumentException e) {
        //            return false;
        //        }
        try {
            return url.contains("spreadsheet") && getSpreadsheetID(new URL(url)) != null;
        } catch (MalformedURLException e) {
            return false;
        }
    }

    static String getSpreadsheetID(URL url) {
        return getParamValue(url, "key");
    }

    static private String getParamValue(URL url, String key) {
        String query = url.getQuery();
        if (query != null) {
            String[] parts = query.split("&");
            for (String part : parts) {
                if (part.startsWith(key + "=")) {
                    int offset = key.length() + 1;
                    String tableId = part.substring(offset);
                    return tableId;
                }
            }
        }
        return null;
    }

}