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.google.analytics.admin; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.joda.time.DateTime; import org.joda.time.format.DateTimeFormat; import org.joda.time.format.DateTimeFormatter; import com.atomicleopard.expressive.EList; import com.atomicleopard.expressive.ETransformer; import com.atomicleopard.expressive.Expressive; import com.google.api.services.analytics.model.GaData; import com.google.api.services.analytics.model.GaData.ColumnHeaders; import com.threewks.thundr.google.analytics.Dimension; import com.threewks.thundr.google.analytics.GoogleAnalyticsServiceImpl; import com.threewks.thundr.google.analytics.Metric; import com.threewks.thundr.view.file.FileView; import com.threewks.thundr.view.handlebars.HandlebarsView; import com.threewks.thundr.view.json.JsonView; public class AnalyticsController { private static final DateTimeFormatter formatter = DateTimeFormat.forPattern("dd/MM/yyyy"); private GoogleAnalyticsServiceImpl analyticsServer; private String profile; private String ua; private String profileId; public AnalyticsController(GoogleAnalyticsServiceImpl googleAnalyticsService, String googleAnalyticsUA, String googleAnalyticsProfile) { this.analyticsServer = googleAnalyticsService; this.ua = googleAnalyticsUA; this.profile = googleAnalyticsProfile; } public HandlebarsView analytics(List<String> metrics, List<String> dimensions, String from, String to) { DateTime fromDate = parseFromDate(from); DateTime toDate = parseToDate(to); GaData results = fetchAnalytics(parseMetrics(metrics), parseDimensions(dimensions), fromDate, toDate); Map<String, Object> model = new HashMap<String, Object>(); // result data model.put("headers", results.getColumnHeaders()); model.put("results", results.getRows()); // reference data model.put("metrics", Metric.metrics); model.put("dimensions", Dimension.dimensions); // selections model.put("from", fromDate.toString(formatter)); model.put("to", toDate.toString(formatter)); return new HandlebarsView("/com/threewks/thundr/google/analytics/analytics.hbs", model); } public JsonView analyticsJson(List<String> metrics, List<String> dimensions, String from, String to) { DateTime fromDate = parseFromDate(from); DateTime toDate = parseToDate(to); GaData results = fetchAnalytics(parseMetrics(metrics), parseDimensions(dimensions), fromDate, toDate); List<ColumnHeaders> columnHeaders = results.getColumnHeaders(); List<List<String>> rows = results.getRows(); Map<String, Object> model = new HashMap<String, Object>(); model.put("headers", columnHeaders); model.put("results", rows); return new JsonView(model); } public FileView analyticsCsv(List<String> metrics, List<String> dimensions, String from, String to) throws UnsupportedEncodingException { DateTime fromDate = parseFromDate(from); DateTime toDate = parseToDate(to); GaData results = fetchAnalytics(parseMetrics(metrics), parseDimensions(dimensions), fromDate, toDate); List<String> columnNames = Transformers.columnNames.from(results.getColumnHeaders()); StringBuilder csv = new StringBuilder(); csv.append(simpleCsvRow(columnNames)); for (List<String> row : results.getRows()) { csv.append(simpleCsvRow(row)); } return new FileView("analytics.csv", csv.toString().getBytes("UTF-8"), "text/csv"); } private String simpleCsvRow(List<String> data) { List<String> escapedData = new ArrayList<String>(data.size()); for (String cell : data) { if (StringUtils.containsAny(cell, ",\"")) { cell = "\"" + cell.replaceAll("\"", "\\\"") + "\""; } escapedData.add(cell); } return StringUtils.join(escapedData, ", ") + "\n"; } @SuppressWarnings("unchecked") private GaData fetchAnalytics(EList<Metric> metrics, EList<Dimension> dimensions, DateTime fromDate, DateTime toDate) { if (metrics.isEmpty()) { // generate empty results List<ColumnHeaders> headers = Expressive.list(); List<List<String>> rows = Expressive.list(); return new GaData().setColumnHeaders(headers).setRows(rows); } else { String profileId = fetchOrCacheId(); return analyticsServer.queryRaw(profileId, fromDate, toDate, dimensions, metrics); } } private synchronized String fetchOrCacheId() { if (profileId == null) { profileId = analyticsServer.getProfileId(this.ua, this.profile); } return profileId; } private DateTime parseToDate(String to) { return parseDate(to, new DateTime().minusDays(1)); } private DateTime parseFromDate(String from) { return parseDate(from, new DateTime().minusMonths(1)); } private DateTime parseDate(String date, DateTime defaultDate) { try { return DateTime.parse(date, formatter); } catch (Exception e) { return defaultDate; } } private EList<Dimension> parseDimensions(List<String> from) { return from == null || from.isEmpty() ? Expressive.<Dimension>list() : Dimension.Transformers.toDimensions.from(from); } private EList<Metric> parseMetrics(List<String> from) { return from == null || from.isEmpty() ? Expressive.<Metric>list() : Metric.Transformers.toMetrics.from(from); } private static class Transformers { public static final ETransformer<ColumnHeaders, String> columnName = Expressive.Transformers .toProperty("name", ColumnHeaders.class); public static final ETransformer<Iterable<ColumnHeaders>, EList<String>> columnNames = Expressive.Transformers .transformAllUsing(columnName); } }