/* * Copyright (C) 2011 Artur Suilin * 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. */ /** * * Центральный класс Metrika4j - {@link ru.metrika4j.MetrikaApi}. В нем есть методы для работы с главными сущностями * Яндекс.Метрики: * счетчиками и отчетами. Работа с дополнительными сущностями (Цели, Фильтры, etc) вынесена в отдельные мини-API, * получаемые из главного * класса {@code MetrikaApi} c помощью методов {@code getXxxApi()}, например API целей {@link ru.metrika4j.MetrikaApi#getGoalApi()}.<br> * Структура методов примерно соответствует структуре REST-вызовов. Один REST-вызов = один метод. * Аргументы, передаваемые в REST-вызов, соответствуют аргументам, передаваемым в методы API (кроме API работы * с отчетами).<br> * Все сущности (счетчики, цели, фильтры, etc) - POJO объекты, без какой либо бизнес-логики. * * <h3>Подготовка к использованию Metrika4j </h3> * Прежде всего надо получить OAuth токен. В Metrika4j нет функций, связанных c OAuth авторизацией: предполагается, * что пользователь самостоятельно получает OAuth токен доступными ему способами, и передаёт в API уже готовый токен. * Процедура получения токена описана <a href="http://api.yandex.ru/metrika/doc/ref/concepts/authorization * .xml">здесь</a>.<br> * Далее, надо выбрать, с помощью чего обрабатывать JSON. В Metrika4j есть встроенная поддержка * <a href="http://jackson.codehaus.org">Jackson JSON-processor</a> (полноценный маппинг) и библиотеки org.json, * как lightweight * варианта, удобного для использования под Android (реализовано только чтение счетчиков и работа с отчетами). * * Можно подключить любой другой JSON процессор, создав c его помощью имплементации интерфейсов {@link ru.metrika4j.json.JsonMapper} * и {@link ru.metrika4j.json.JsonObject}. Готовые имплементации, включенные в Metrika4j - это * {@link ru.metrika4j.json.jackson.JacksonMapper} и {@link ru.metrika4j.json.org.OrgJsonMapper}<br> * * <h3>Начало работы с Metrika4j</h3> * Сначала необходимо создать экземпляр {@link ru.metrika4j.MetrikaApi} c помощью {@link ru.metrika4j.ApiFactory} * <pre> * // Создаем экземпляр API, использующий Jackson JSON-processor и транспорт по умолчанию * MetrikaApi api = ApiFactory.createMetrikaAPI("05dd3dd84ff948fdae2bc4fb91f13e22", new JacksonMapper()); * </pre> * Если HTTP транспорт по умолчанию (использующий стандартный {@code HttpUrlConnection} из JDK) не устраивает, * можно создать свой транспорт, имплементировав {@link ru.metrika4j.http.HttpTransport}. Транспорт должен получать * OAuth токен при создании и передавать его в каждом запросе к серверам Метрики. * <pre> * // Создаём транспорт, передав в него OAuth токен * HttpTransport transport = new MyTransport("05dd3dd84ff948fdae2bc4fb91f13e22"); * * // Создаем экземпляр API, использующий Jackson JSON-processor и заданный транспорт * MetrikaApi api = ApiFactory.createMetrikaAPI(transport, new JacksonMapper()); * </pre> * Полученный экземпляр API полностью thread-safe, поэтому на все приложение достаточно только одного экземпляра. * * <h3>Работа со счетчиками</h3> * <pre> * // Получаем список счетчиков в текущем аккаунте * Counter[] myCounters = api.getCounters(); * </pre> * По умолчанию в полученных счетчиках не будет заполнена часть полей (цели, фильтры, зеркала и т.п.). Чтобы заполнить * их, надо при чтении счетчиков указать, какая детализация нужна * <pre> * // Получаем счетчики с заполненными целями и фильтрами * Counter[] myCounters = api.getCounters(CounterDetails.goals, CounterDetails.filters); * // Получаем счетчики с полной детализацией * Counter[] detailedCounters = api.getCounters(CounterDetails.values()); * </pre> * При повышении детализации будет увеличиваться время ответа и объем передаваемой информации, поэтому лучше * не злоупотреблять высокой детализацией. * <pre> * // Создание счетчика * Counter newCounter = new Counter(); * newCounter.setSite("mysite.ru"); * newCounter.setName("Мой сайт"); * Counter createdCounter = api.createCounter(newCounter); * // В createdCounter содержится новый счетчик, загруженный из Метрики, со всем значениями полей, проставленными Метрикой * System.out.println(createdCounter.getId()); * </pre> * <pre> * // Удаление счетчика * api.deleteCounter(createdCounter.id); * </pre> * <h3>Работа с отчетами</h3> * Набор доступных отчетов содержится в enum-e {@link ru.metrika4j.Reports}. Для построения отчета надо вызвать метод * {@link ru.metrika4j.MetrikaApi#makeReportBuilder(Reports, int)}, который вернет объект {@link ru.metrika4j.ReportBuilder} * - построитель отчета. * В построителе отчета можно задать параметры отчета (временной интервал, сортировку и т.п.). Когда все параметры будут * установлены, вызывайте метод {@link ru.metrika4j.ReportBuilder#build()}, который отправит запрос на сервер API * Метрики и вернет результат. * <pre> * // Создаем построитель отчета "популярное содержимое" для счетчика с id=2138128 * ReportBuilder builder = api.makeReportBuilder(Reports.contentPopular, 2138128); * * // Задаём параметры отчета (отчет за неделю) и строим отчет * Report report = builder.withDateFrom(MetrikaDate.yesterday()).withDateTo(MetrikaDate.today()).build(); * </pre> * Отчет возвращается в виде объекта {@link ru.metrika4j.Report}, представляющего собой таблицу с результатами, плюс некоторая * дополнительная информация (итоги, интервал дат, к которым относится отчет и т.п.). Каждая строка таблицы результатов - * объект {@link ru.metrika4j.ReportItem}, данные из которого можно получить одним из методов {@code getXXX(String fieldName)} * (аналогично получению значений из JDBC ResultSet). Имена полей и возвращаемые дополнительные данные надо уточнять * для каждого отчета в документации на API Яндекс.Метрики * <pre> * // Вытаскиваем результаты из отчета * ReportItem[] items = report.getData(); * for (ReportItem item : items) { * System.out.printf("pageViews: %4d, url: %s", item.getInt("page_views"), item.getString("url")).println(); * } * </pre> * Некоторые отчеты бывают не только табличные, но и древовидные. Для получения древовидного отчета надо задать * в {@code ReportBuilder} соответствующий режим. * <pre> * // Строим такой же отчет, но древовидный * report = builder.withTableMode(ReportBuilder.TableMode.tree).build(); * // Отображаем первые два уровня * items = report.getData(); * for (ReportItem item : items) { * // Первый уровень * System.out * .printf("Level 1, pageViews: %4d, url: %s", item.getInt("page_views"), item.getString("url")) * .println(); * ReportItem[] children = item.getArray("chld"); * if (children != null) { * for (ReportItem child : children) { * // Второй уровень * System.out * .printf(" Level 2, pageviews: %4d, url: %s", child.getInt("page_views"), * child.getString("url")) * .println(); * } * } * } * </pre> * <h3>Обработка ошибок</h3> * Все ошибки, возникающие в ходе работы Metrika4j, унаследованы от базового класса {@link ru.metrika4j.error.Metrika4jException}. * Ошибки могут возникнуть только в момент обращения к серверам API Метрики. Картина такова: * <ul> * <li>Если произошла ошибка в момент формирования обращения к серверу (не удалось сериализовать сущность в JSON), возникает {@link ru.metrika4j.error.JsonSerializationException}</li> * <li>Если произошел сбой на транспортном уровне (ошибка сокета, плохой HTTP ответ), возникает {@link ru.metrika4j.error.TransportException}</li> * <li>Если произошла ошибка авторизации (невалидный OAuth токен), возникает {@link ru.metrika4j.error.AuthException}</li> * <li>Если сервер вернул JSON ответ, который не удалось распарсить, возникает {@link ru.metrika4j.error.ParseException}</li> * <li>Если сервер вернул код ошибки (например при неправильных параметрах вызова), возникает * {@link ru.metrika4j.error.ServerException}, в который передаются возвращенные сервером ошибки </li> * <li>Если сервер Я.Метрики не нашел данных для отчета (например был задан интервал дат, в котором не содержится данных), * возникает {@link ru.metrika4j.error.NoDataException}</li> * </ul> * * * <h3>Thread safety</h3> * Все основные классы Metrika4j не содержат состояния (stateless). API Я.Метрики также работает через stateless REST интерфейс. * Это означает, что можно делать параллельные запросы из нескольких потоков, используя один экземпляр {@code MetrikaApi} * Каждый полученный отчет потом должен обрабатываться в рамках одного потока, т.к. thread safety библиотек, выгружающих * данные из JSON ответов, не гарантируется. * */ package ru.metrika4j;