com.streamreduce.util.GoogleAnalyticsClient.java Source code

Java tutorial

Introduction

Here is the source code for com.streamreduce.util.GoogleAnalyticsClient.java

Source

/*
 * Copyright 2012 Nodeable Inc
 *
 *    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.streamreduce.util;

import com.google.api.client.auth.oauth2.TokenResponse;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.jackson.JacksonFactory;
import com.google.api.services.analytics.Analytics;
import com.google.api.services.analytics.model.Account;
import com.google.api.services.analytics.model.Accounts;
import com.google.api.services.analytics.model.GaData;
import com.google.api.services.analytics.model.Profile;
import com.google.api.services.analytics.model.Profiles;
import com.google.api.services.analytics.model.Webproperties;
import com.google.api.services.analytics.model.Webproperty;
import com.google.common.collect.Lists;
import com.streamreduce.connections.GoogleAnalyticsProvider;
import com.streamreduce.core.model.Connection;
import com.streamreduce.core.service.exception.InvalidCredentialsException;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

import java.io.IOException;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>Author: Nick Heudecker</p>
 * <p>Created: 9/4/12 13:29</p>
 */
public class GoogleAnalyticsClient extends ExternalIntegrationClient {

    public static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormat.forPattern("yyyy-MM-dd");

    private JacksonFactory jsonFactory = new JacksonFactory();
    private NetHttpTransport transport = new NetHttpTransport();
    private Analytics analytics;

    public GoogleAnalyticsClient(Connection connection) {
        super(connection);
    }

    @Override
    public void validateConnection() throws InvalidCredentialsException, IOException {
        List<JSONObject> profileIds = getProfiles();
        if (CollectionUtils.isEmpty(profileIds)) {
            throw new InvalidCredentialsException(
                    "You must have one or more profiles defined in Google Analytics in order to continue.");
        }
    }

    public List<JSONObject> getProfiles() throws IOException {
        Analytics analytics = initializeAnalytics();
        Accounts accounts = analytics.management().accounts().list().execute();

        List<JSONObject> jsonProfiles = Lists.newArrayList();

        if (accounts.getItems().isEmpty()) {
            System.err.println("No accounts found");
        } else {
            for (Account account : accounts.getItems()) {
                String accountId = account.getId();

                // Query webproperties collection.
                Webproperties webproperties = analytics.management().webproperties().list(accountId).execute();

                if (webproperties.getItems().isEmpty()) {
                    System.err.println("No Webproperties found");
                } else {
                    for (Webproperty webproperty : webproperties.getItems()) {
                        String webpropertyId = webproperty.getId();

                        // Query profiles collection.
                        Profiles profiles = analytics.management().profiles().list(accountId, webpropertyId)
                                .execute();
                        if (profiles.getItems().isEmpty()) {
                            System.err.println("No profiles found");
                        } else {
                            for (Profile profile : profiles.getItems()) {
                                jsonProfiles.add(new JSONObjectBuilder().add("id", profile.getId())
                                        .add("name", profile.getName()).build());
                            }
                        }
                    }
                }
            }
        }
        return jsonProfiles;
    }

    public JSONObject getProfileMetrics(String profileId) throws IOException {
        String formattedToday = DATE_TIME_FORMATTER.print(new DateTime());
        Analytics analytics = initializeAnalytics();
        GaData data = analytics.data().ga()
                .get("ga:" + profileId, formattedToday, formattedToday, "ga:visitors,ga:newVisits").execute();

        if (CollectionUtils.isEmpty(data.getRows())) {
            return null;
        }

        JSONObjectBuilder builder = new JSONObjectBuilder();
        builder.add("id", profileId);
        int columnIndex = 0;
        for (GaData.ColumnHeaders header : data.getColumnHeaders()) {
            JSONObjectBuilder metric = new JSONObjectBuilder();
            String metricName = normalizeMetricName(header.getName());
            metric.add("metric", metricName);
            metric.add("id", profileId);
            Set<String> hashtags = new HashSet<>();
            hashtags.add(metricName.toLowerCase());

            for (List<String> row : data.getRows()) {
                for (int rowIndex = 0; rowIndex < row.size(); rowIndex++) {
                    if (rowIndex == columnIndex) {
                        metric.add("data", new Float(row.get(rowIndex)));
                    }
                }
            }

            hashtags.add("googleanalytics");
            metric.add("hashtags", hashtags);
            builder.append("metrics", metric.build());
            columnIndex++;
        }

        return builder.build();
    }

    public List<JSONObject> getAllProfileMetrics(Set<String> profileIds) throws IOException {
        List<JSONObject> allProfileMetrics = Lists.newArrayList();
        for (String profileId : profileIds) {
            allProfileMetrics.add(getProfileMetrics(profileId));
        }
        return allProfileMetrics;
    }

    private Analytics initializeAnalytics() {
        if (analytics == null) {
            GoogleAnalyticsProvider provider = new GoogleAnalyticsProvider();
            TokenResponse tokenResponse = new TokenResponse()
                    .setRefreshToken(getConnectionCredentials().getOauthRefreshToken());
            GoogleCredential credential = new GoogleCredential.Builder().setJsonFactory(jsonFactory)
                    .setTransport(transport).setClientSecrets(provider.getClientId(), provider.getClientSecret())
                    .build().setFromTokenResponse(tokenResponse);
            analytics = new Analytics.Builder(transport, jsonFactory, credential).build();
        }
        return analytics;
    }

    private String normalizeMetricName(String name) {
        if (name.startsWith("ga:")) {
            return name.substring(3, name.length());
        } else {
            return name;
        }
    }
}