ITI0011RUS:Tweets

Allikas: Kursused
Mine navigeerimisribale Mine otsikasti

Вернуться на страницу предмета

Задание дополняется!

Срок сдачи 6. - 7. апреля.

Описание задания

Программа должна делать запрос в социальную сеть Twitter и получать оттуда список твитов. Запрос делается на недавно добавленные твиты по заданному месторасположению и их список показывается пользователю.

Функционал:

  • Считвается место, которое задается пользователем (например, Tallinn)
  • Программа узнает географические координаты введенного места (широта, долгота)
  • полученные географические координаты используются, для задания точки и радиуса, где следует искать твиты
  • Используя Twitter API посылается запрос, в него передаются координаты точки центра и радиус.
  • Ответ Twitteri API принимается, оттуда считываются необходимые данные и выводятся на экран.
  • Программе можно задать место также в виде параметра при запуске.

Дополнительные части:

  • Буферизация мест в файл (чтобы не нужно было каждый раз искать, например, координаты Таллинна, которые не меняются).
  • Сортировка твитов
  • Интерактивное управление программой
  • Тестируемый код (составление программы в соответствии с шаблоном)

Дополнительная информация

Координаты места

Используем сервис OpenStreetMap Nominatim (Nominatim wiki leht). Следует отослать сервису запрос, в котором следует указать желаемое месторасположение, и в ответе получите координаты искомого места (широту и долготу) и координаты квадрата, окружающего эту центральную точку (bounding box).

Пример запроса: http://nominatim.openstreetmap.org/search?q=Tallinn&format=xml

Отослав такой запрос получите результат (в целях компактности показана лишь самая важная часть ответа):

<searchresults timestamp="Sat, 13 Sep 14 21:47:21 +0000" 
attribution="Data © OpenStreetMap contributors, ODbL 1.0. http://www.openstreetmap.org/copyright" 
querystring="Tallinn" polygon="false" 
exclude_place_ids="98174326,11438224,6000303521,6919504,6893196,86869124,15103978,5983246058" 
more_url="http://nominatim.openstreetmap.org/search?format=xml&
exclude_place_ids=98174326,11438224,6000303521,6919504,6893196,86869124,15103978,5983246058&accept-language=en-
US,en;q=0.5&q=Tallinn">
<place place_id="98174326" osm_type="relation" osm_id="2164745" place_rank="16" 
boundingbox="59.351806640625,59.5915794372559,24.5501689910889,24.9262847900391" lat="59.4372155" 
lon="24.7453688" display_name="Tallinn, Harju maakond, Estonia" class="place" type="city" 
importance="0.7819722223575" icon="http://nominatim.openstreetmap.org/images/mapicons/poi_place_city.p.20.png"/>
...
</searchresults>

В результате получите несколько различных мест с именем Tallinn (или в названии которых содержится это слово). Самая первая запись для нас подойдет. Таким образом, вы считываете первую запись под элементом "place". Поскольку для отсылки запроса в Twitter нам понадобятся координаты центра и радиус (поскольку ищем результаты с большой площади), то интересующие нас атрибуты "lat" и "lon" (широта и долгота), которые обозначают координаты центральной точки, а также атрибут "boundingbox", который задает линию, ограничивающие окрестности данной точки. В данном примере lat="59.4372155", lon="24.7453688", boundingbox="59.351806640625,59.5915794372559,24.5501689910889,24.9262847900391".

Область поиска в Twitter-е задается точкой центра и радиусом. В качестве центральной точки можно использовать полученные значения "lat" и "lon" напрямую. Для вычисления радиуса следует использовать значение "boundingbox". Поскольку радиус должен быть представлен в километрах, то следует то параметрам boundingbox высчитать радиус. Внимание, в различных областях земного шара длина широты может различаться. В рамках данного задания точно высчитать радиус не требуется. Будет достаточно приблизительного значения. Здесь в описании задания никакой конкретной формулы или примера не приведено - это вам следует придумать самим. Важно, чтобы города, чьи размеры заметно отличаются, давали бы разный радиус (New York > > Tallinn > Haapsalu).

Для вас важно, что вы можете требуемые данные прочесть и преобразовать к точке центра и радиусу.

Примечание. Для решения основной части достаточно и того, если вы будете пользоваться любым другим API (например, Google Maps).

Twitter API

Twitter API (https://dev.twitter.com/docs/api/1.1) позволяет делать программе запросы в Twitter . Для решения данного задания не требуется, чтобы вы были активным пользователем Twitter.

Для использования Twitteri API вам все же необходимо создать аккаунт. После логина, можете увидеть свои приложения на этой странице: https://apps.twitter.com/ (эта ссылка также доступна по адресу dev.twitter.com внизу страницы в списке "TOOLS"). Там создайте свое приложение, где в качестве домашней страницы можете записать любой адрес URL (хоть страницу этого предмета).

После того, как приложение создано, вы увидите его в списке своих приложений. Если откроете созданное приложение, то в разделе "API keys" увидите настройки приложения. Нас интересуют данные "API key" и "API secret". Эти два значения нужны для отправления запросов к Twitter API.

Сам запрос, который слеует использовать, описан здесь: https://dev.twitter.com/rest/public/search ja https://dev.twitter.com/rest/reference/get/search/tweets

Например, запрос может быть таким: https://api.twitter.com/1.1/search/tweets.json?q=&geocode=59.437215524.7453688,1km&result_type=recent

Ссылка выше может не дать никакого результата, если вы не залогинены. Она должна давать твиты с месторасположением Tallinn в радиусе 1 км.

Немного информации о том, как авторизовать приложение для использования Twitteri API: https://dev.twitter.com/oauth .

Для того, чтобы весь процесс не был слишком сложным, при решении задания советуем пользоваться библиотекой, которая может провести аутентификацию и отослать запрос за вам. Одна такая библиотека, о которой ниже также будет пара примеров кода, нахоится здесь: http://twitter4j.org/ . При желании, можете воспользоваться любой другой.

Если вы используете twitter4j, вам нужно получить следующий файл: twitter4j-core-4.0.2.jar. Когда скачаете архив в zip-формате, этот файл будет располагаться в директории "lib". Во время написания этого руководства текущая венсия библиотеки была 4.0.2, она может в любой момент измениться - соответственно, изменятся и имена файлов. Этот jar-файд следует добавить в свой проект Eclipse: project properties > java build path > libraries > add external jars ... и найдите этот файл.

Сконфигурировать библиотеку можно следующим образом: <source lang="java"> ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setDebugEnabled(true) .setApplicationOnlyAuthEnabled(true); cb.setOAuthConsumerKey(TWITTER_CUSTOMER_KEY) .setOAuthConsumerSecret(TWITTER_CUSTOMER_SECRET);

TwitterFactory tf = new TwitterFactory(cb.build()); twitter4j.Twitter twitter = tf.getInstance();

OAuth2Token token; try { token = twitter.getOAuth2Token(); } catch (TwitterException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } </source>

В примере выше значения констант TWITTER_CUSTOMER_KEY и TWITTER_CUSTOMER_SECRET взяты из настроек приложения с веб страницы (application key и application secret соответственно). Альтернативно, можете настроить библиотеку при помощи конфигурационного файла, или другими способами (больше об этом можете прочитать на веб странице библиотеки, которую вы используете).

То, как отправить запрос выбранной библиотекой, вы должны выяснить сами. Об этом на странице библиотеки должна быть пара примеров. Здесь также один пример: https://github.com/yusuke/twitter4j/blob/master/twitter4j-core/src/test/java/twitter4j/SearchAPITest.java (Он взят из директории тестов. Часто тесты содержат больше примеров кода, чем сами примеры.)

Если у вас есть Twitter аккаунт, вы можете создать в нем приложение. Так как целью задания является отправка запросов на получение открытых твитов, вы можете сделать приложение, которое запрашивает твиты, связанные с вашим аккаунтом (или, например, с аккаунтом ваших друзей). Однако, в общем случае это не дает дополнительных баллов. Обратите внимание, если вы запрашиваете твиты своих друзей, кроме ключей приложения вам будет необходимо добавить и ключи своего аккаунта. Примеры найдете здесь: http://twitter4j.org/en/configuration.html Все примеры рассмотрены для случая, когда запросы делаются от конвретного пользователя. Если вы не добавляете данные о своем аккаунте, можно запрашивать открытые твиты.

Основная часть (5 баллов)

В основной части из командной строки берется месторасположение (и, есть указано, количество запрашиваемых твитов), программа ищет координаты этого места. Далее, из полученных координат и вычисленного радиуса формируется и делается запрос на Твиттер. Результаты запроса показываются пользователю. Задание должно быть реализовано без компонентов графического интерфейса. Если вы используете какие-то компоненты и это не мешает тестированию (методы всех интерфейсов работают и делают, что и требовалось), тогда баллы не снимаются. Однако желательно не использовать графический компоненты (для этого есть следующая домашняя работа). В основной части работы от пользователя не ожидается никаких входных данных («введите город», «сделать еще один запрос?»). Аналогично, не следует показывать никаких окон/диалогов (в этом случае закрытие окна уже считается вводом данных от пользователя) В дополнительной части Интерактивный интерфейс ожидание ввода данных от пользователя является обязательным (чтобы получить баллы).

Основная часть: управление из командной строки

Программа должна быть управляемой из командной строки, например (в случае, если у вас сделаны соответствующие дополнительные части задания):

java Twitter Tallinn -count 50 -sort date desc -search tere

Запуск основной части программы происходит так:

java Twitter Tallinn

где:

  • java - сама java, которя запустит вашу программу.
  • Twitter - имя класса, который запускается
  • Tallinn - место, по которому будет происходить поиск твитов.

Таким образом при запуске вашей программе дается один аргумент: "Tallinn"

Другой вариант запуска основной части программы (запрашивается 40 твитов): java Twitter Tallinn -count 40

Если программа запускается без аргументов, необходимо показать пользователю руководство по запуску программы.

Аргументы, которые программа должна распознавать:

  • -help (основная часть) — показывает пользователю руководство по запуску программы. После это программа завершает работу с кодом 1 (exit code). Эти же инструкции по запуску программы показываются в случае (exit code тоже равен 1), если программа запускается без аргументов или если введенные аргументы неверные
  • -count num (основная часть) — устанавливает, сколько твитов показывается. Если этот аргумент отсутствует, тогда по умолчанию берется значение 15.
  • -sort field [asc|desc] (дополнительная часть) — указывает, как сортируются твиты перед отображением на экране. Поле может быть : author, date или tweet. Можно указать необязательный параметр  asc или desc. В первом случае сортировка происходит по возрастанию, во втором — по убыванию. Если этот параметр не указан, то по умолчанию твиты сортируются по возрастанию. См. соответствующее дополнительное задание. Пример: -sort author asc и-sort author дают одинаковые результаты
  • -search keyword (дополнительная часть) — отображаются только те твиты, которые содержат искомое слово.
  • ...

Аргументы могут идти в любом порядке, но первый аргумент всегда месторасположение. Таким образом, такие два варианта запуска должны дать одинаковый результат: java Twitter Tallinn -count 50 -sort date desc -search tere java Twitter Tallinn -search tere -sort date desc -count 50

Дополнительное задание: буферизация месторасположений (2 балла)

Так как координаты мест со временем не меняются, то нет смысла каждый раз, когда пользователь вводит Tallinn, делать новый запрос на координаты. Вероятно, результат будет таким же, как и в предыдущем запросе. В связи с этим имело бы смысл сохранять результаты в какой-нибудь буфер (файл) и потом оттуда считывать данные. Функциональность этого дополнительного задания:

  • результаты запроса координат сохраняются в файл, чтобы в следующих раз снова не делать запрос (локальный cache)
  • в этот файл можно добавить альтернативные имена мест (например, "дом", "TTÜ" и т.д.)

По умолчанию в качестве буфера использовать файл "kohad.csv", который должен быть доступен вашей программе (рекомендуется расположить его в той же папка, что и запускаемый класс) и должен быть в формате CSV и состоять из следующих строк: ametlik_nimi,latitude,longitude,raadius_km,alternatiivnenimi_1,..,alternatiivnenimi_N или строк, где координаты и радиус отсутствуют: ametlik_nimi,,,,alternatiivnenimi_1,...,alternatiivnenimi_N где:

  • ametlik_nimi - место, которое запрашивается из API (например,  tallinn)
  • alternatiivnimi_1, ..., alternatiivnimi_N — имена, которые пользователь может сохранить. Например, пользователь может сюда записать «дом». Если происходит соответствующий запрос, то выполняется запрос по ametlik_nimi (или же используются уже существующие координаты, если они есть) (например kodu,elupaik)
  • latitude, longitude ja raadius_km — в обычном их значении. Эти значения могут отсутствовать. (например, : 59.4,24.5,10)

Программа использует буфер следующим образом:

  • Перед запросом координат у API программа смотрит, если ли данное место в буфере
  • Если да, и координаты уже есть, то программа использует эти координаты и запрос на координаты не делается
  • Если да, но координаты отсутствуют, то делается запрос координат у API по месторасположению, находятся координаты и вычисляется радиус.
  • Полученные координаты и радиус дописывается в соответствующую строку. Далее, при запросе по такому же местоположению, запрос координат не происходит.
  • Если нет, то делается новый запрос и данные записываются в буфер (файл) (записывается новая строка с названием места, его координатами и радиусом: pärnu,58.3800572,24.5200466,5).

Примеры: 1) kohad.csv: tallinn,59.4,24.5,10,kodu,ttü

Если делается запрос "tallinn", тогда используются координаты 59.4 и 24.5, радиус = 10km. Тоже происходит и при запросах "ttü", "kodu". Файл kohad.csv не меняется.

2) kohad.csv: pärnu,,,,vanaema,suvila

Если делается запрос "pärnu", или "vanaema", или "suvila", тогда в API посылается запрос "pärnu", считываются координаты и вычисляется радиус. Эта же строка после запроса: pärnu,58.3,24.5,5,vanaema,suvila

3) kohad.csv: tallinn,59.4,24.5,10,kodu,ttü

Если происходит поиск "pärnu", тогда делается запрос координат "pärnu" и получаенные координаты вместе с радиусом сохраняются в файл. Результат:

tallinn,59.4,24.5,10,kodu,ttü pärnu,58.3,24.5,5

4) kohad.csv: tallinn,59.4,24.5,10,kodu,pärnu pärnu,58.3,24.5,5

Если делается запрос "pärnu", то используются соответствующие данные из второй строки. Основное название места (ametlik nimi) является более приоритетным по сравнению с альтернативными названиями. Если название места не найдено, тогда поиск происходит по альтернативным названиям. Содержание файла не может быть регистрозависимым, то есть строчные и печатные буквы считаются одинаковыми ("Pärnu", "pärnu" и "PÄRNU" - все это один и тот же запрос). Никаких других операций с файлом (удаление строк и т. д.) ваша программа делать не должна. Редактирование файла происходит вручную. Также, вы не должны ничего делать, если формат файла неправильный. В тоже время, если возникает какая-то проблема при чтении файла, программа не должна завершать работу. Если файл невозможно прочитать, то все запросы делаются из сети. Полностью сделанное, это дополнительное задание дает 2 балла.

Дополнительное задание: сортировка и фильтрация (поиск) (1p)

Позволяет сортировать твиты по введенному полю. Сортировать можно по следующим полям:

  • автор
  • дата твита
  • содержание твита

Сортировать можно как по возрастанию (сначала меньшие, например: a, b, c, ... или 1, 3, 5, …), так и в убывающем порядке (сначала большие, например: ü, ö, ä, ... или 9, 8, 4, ...). Также можно указать и слово для поиска (фильтра). Показываются только те твиты, которые содержат это слово. Полностью сделанное, это дополнительное задание дает 1 балл.

Дополнительное задание: интерактивное управление (1-2p)

Требованием к основной части было то, что программа должна управляться аргументами командной строки: java Twitter Tallinn -count 50 -sort date desc -search tere

Интерактивная среда (2p)

Цель этого задания — создать интерактивную среду, с помощью которой можно управлять программой. Это значит, что программа ожидает от пользователя ввода и выполняет введенные команды. После выполнения команды, программа ждет следующей команды и т. д. (как и командная строка). Например:

> setcount 50  
> query Tallinn
> print
> query Pärnu 10
> sort date desc
> print
> search tere
> print
> exit

Программа должна распознавать следующие команды:

  • query location [count] (основная часть) — делается запрос по заданному месту location. Также сразу можно указать и количество твитов. Однако, результат запроса на экран не отображается(см. print. Например, query Tallinn  делает запрос "Tallinn", количество твитов такое же, как и установленное в последний раз, или по умолчанию — 15. query Pärnu 10  делает запрос "Pärnu" и в качестве количества используется значение 10. Этот запрос не изменяет сохраненное в памяти значение количества твитов (см. setcount)
  • print [count] (основная часть) — отображает результаты последнего запроса. print 10  распечатывает 10 первых твитов из последнего запроса (в случае, если результаты должны быть отсортированы, то сначала берется необходимое количество твитов и только потом они сортируются). Если в результате последнего запроса было получено меньше твитов, то необходимо распечатать все.
  • setcount num (основная часть) — устанавливает количество запрашиваемых твитов. Установленное значение сохраняется и используется в последующих запросах (если количество не указывано, см. query). Например : setcount 30 - далее происходит запрос  query  и с помощью команды  print отображается 30 твитов.
  • sort field [asc|desc] (дополнительная часть) — сортировка результатов. Команда выполняется по отношению к твитам, полученным при последнем запросе. Если после сортировки делается новый запрос, то данные не должны быть отсортированы таким же образом. Поле (field) може принимат значени  author, date или tweet. Дополнительно можно обозначить порядок сортировки: asc - по возрастанию, desc - по убыванию. См #Дополнительноe задание: сортировка и фильтрация (поиск) (1p).
  • search keyword (дополнительная часть) — последний запрос выполняется снова (все то, что было сделано в последнем запросе  query ), на этот раз используется установленное слово для поиска  keyword. Поэтому, если до этого искали "Tallinn" и сейчас выполняется команда  search kevad, то делается новый запрос, в котором искомым словом является "kevad". Если запущена команда  search suvi, делается новый запрос, но на этот раз с ключевым словом "suvi" и так далее.
  • exit (основная часть) — выход из программы.

Корректная реализация вышеуказанных методов дает 1 балл.

Дополнительный балл можно получить. Если логика программы остается абсолютно такой же как в интерактивном режиме, так и при запуске с указанием параметров в командной строке. Команды из разных режимов запуска (аргументы командной строки/интерактивный режим) преобразуются к единому виду и потом уже запускаются. Для программы нет разницы, пришел запрос из командной строки или из потока ввода. Если же у вас возникнет желание дополнить программу таким образом, чтобы она обрабатывала и веб-запросы, то вам будет необходимо их преобразовать к тому же единому формату команд. А сами команды у вас уже будут готовы. Если команды полученные как из командной строки, так и в интерактивном режиме, обрабатываются таким же образом, вы получаете за это дополнительно 1 балл (то есть всего будет 2 балла).

Дополнительное задание (посложнее ): тренды (2p)

Цель этого задания — найти тренды (популярные слова, темы, хеш-теги) для указанного местоположения. На этот раз необходимо отобразить только те твиты, которые «в тренде» (содержат популярные слова, хеш-теги и т. д.). Описание реализации появится в ближайшее время. Однако, если вы выполните это задание каким-то другим образом, также получите баллы. Возможное решение:

Для этого задание будут сделаны дополнительные изменения в шаблоне, чтобы было можно протестировать задание.

Дополнительное задание (посложнее): streaming (2p)

Цель задания — слушать поток Твиттера (stream) и сохранять полученные твиты в файл. Позже будет возможно работать с этим файлом: смотреть все твиты, смотреть статистику (сколько твитов, от скольких пользователей, пользователь, написавший больше всего твитов), поиск. Возможное решение:

Для этого задание будут сделаны дополнительные изменения в шаблоне, чтобы было можно протестировать задание.

Шаблон

Загрузите файлы интервейсов : Meedia:ITI0011-Twitter_interfaces_v0.2.zip (v0.2, 25. märts).

Изменения по сравнению с версией v0.1:

  • FilterAction разделен на 2 разных типа Action: SortAction и SearchAction.
  • Добавлен PrintAction (в интерактивном режиме для распечатки твитов необходим также Action объект)
  • Тип списка твитов изменен с  List<? extends Tweet> на  List<Tweet>.
  • В Action интерфейс добавлен метод  execute, который по умолчанию пустой (то есть ничего не делает). При желании можно использовать этот метод для каждого Action, чтобы выполнять соответствующее действие. Есть также и TwitterApplication.executeAction() метод, который должен выполнять Actioni любых типов. В этом случае можете сделать так, что каждый Action знает сам, как его необходимо запускать.

Замечания по коду: Класс, который реализует интерфейс TwitterApplication, должен содержать метод main, чтобы запустить программу. Все файлы должны быть в одном пакете (папке). Все используемые jar-файлы нужно положить в папку lib (HW2/lib/twitter4j.jar, например). Кроме twitter4j можете использовать и другие библиотеки Текущий шаблон не содержит интерфейсов для дополнительных заданий посложнее.

TwitterApplication.java: <source lang="java">


import java.util.List;

/**

* The core interface for your application.

*

* The setup of this class is the following: *

    *
  • in the constructor (not described here) * all the different service objects should be set. * E.g. setLocationSearch(), setTwitterSearch(), setCache() etc. *
  • the actual start of the application is done with: * application.run(args); *

*

* The constructor of the class which implements TwitterApplication * could be the following: *

 * public AwesomeTwitterApplication() {
 *     LocationSearch locSearch = new AwesomeLocationSearch();
 *     this.setLocationSearch(locSearch);
 *     Cache cache = new AwesomeCache();
 *     this.setCache(cache);
 *     TwitterSearch twitterSearch = new AwesomeTwitterSearch();
 *     this.setTwitterSearch(twitterSearch);
 * }
 * 
* 
* Constructor should not do anything else. The actual execution
* of the program starts with run(args).

*

* Setting all your implementations of the services in the constructor * gives the test system opportunity to test each one of those. * @author Ago * @see TwitterApplication#run(String[]) * */ public interface TwitterApplication { /** * The application will be run using arguments * from the command line (should be passed here * directly from the main method). * runWithArgs() method will be called. *

* If the arguments are empty, runInteractive() is run. * * @param args Arguments from command line (the same * which are passed to the main method). * @see TwitterApplication#runWithArgs(String[]) * @see TwitterApplication#runInteractive() */ default public void run(String[] args) { if (args.length == 0) { runInteractive(); } else { runWithArgs(args); } } /** * Tries to run the program with command line * arguments. *

* If command line arguments are not correct, * the program can exit with an error code. * @param args Arguments from command line. */ public void runWithArgs(String[] args); /** * The application will be run in an interactive mode * where the user can enter different statements * to control the program. */ public void runInteractive(); /** * Given a command as a String (in interactive mode), * this method should parse the input and return * a list of Action instances. * Usually one command should create one action, this * method gives the opportunity to have combined actions * for one command line ("query tallinn 30" - query + count). * If you don't use combined actions, just return a list * with one element in it - the Action instance to be * executed. * @param action Command string from interactive mode * @return List of actions to be executed */ public List<Action> getActionsFromInput(String action); /** * Given command line arguments this method parses * the arguments and returns a list of Action instances. * As the command line can accept several different actions * (for example query, sort and search), this method * return a list of all the actions. * @param args Command line arguments (from main method) * @return List of actions to be executed */ public List<Action> getActionsFromArguments(String[] args); /** * Given an instance of Action, it will be executed. * If you choose to implement Action.execute() * for every action, then the body of this method can just be: * action.execute() * @param action Action to be executed */ public void executeAction(Action action); /** * Executes all the actions given as a list. * The default implementation just iterates over * all the actions and calls executeAction. * @param actions A list of actions */ default public void executeActions(List<Action> actions) { for (Action action : actions) { executeAction(action); } } /** * Executes a location search using location search set with * setLocationSearch(). * Returns a query object which holds all the values for Twitter search. * Note that this method has a default implementation which * just executes a method from local location search and * returns its return value. * Use this default implementation if you don't have caching implemented. * If you need caching, you need to override this method. * @param location The location which is to be searched for * @return Query object which holds all the necessary information * about Twitter query * @see TwitterApplication#setLocationSearch(LocationSearch) */ default public TwitterQuery getQueryFromLocation(String location) { LocationSearch locationSearch = getLocationSearch(); return locationSearch.getQueryFromLocation(location); } /** * Executes a search of tweets on TwitterSearch object which * is stored via setTwitterSearch(). * Returns a list of received tweets. * @param query Query object which holds all the necessary values * @return List of Tweet objects received from Twitter search. * null if nothing received. * @see TwitterApplication#setTwitterSearch(TwitterSearch) */ default public List<Tweet> getTweets(TwitterQuery query) { TwitterSearch twitterSearch = getTwitterSearch(); return twitterSearch.getTweets(query); } /** * Stores location search object which will * be used to make queries to location search API. * This should be called from the constructor. * @param locationSearch Implementation of LocationSearch, which * can find information about location (city, country etc.). */ public void setLocationSearch(LocationSearch locationSearch); /** * Returns currently stored location search object. * @return Implementation of LocationSeach * which will be used for location search. */ public LocationSearch getLocationSearch(); /** * Stores Twitter search object which will be used * to query tweets from Twitter API. * Should be called from the constructor. * @param twitterSearch Implementation of TwitterSearch */ public void setTwitterSearch(TwitterSearch twitterSearch); /** * Returns currently stored Twitter search object. * @return Implementation of TwitterSearch * which will be used for queries. */ public TwitterSearch getTwitterSearch(); /** * Stores cache object which will be used * to cache locations in the file. * Should be called from the constructor. * @param cache Implementation of Cache */ public void setCache(Cache cache); /** * Returns currently stored cache object. * @return Implementation of Cache * which will be used for location caching. */ public Cache getCache(); /** * Stores the latest state of tweets list. * You should store your tweets using this * method after querying, sorting, searching. * @param tweets A list of tweets */ public void setTweets(List<Tweet> tweets); /** * Get the latest state of tweets list. * This method should be used for printing * and when applying sorting. * @return A list of tweets */ public List<Tweet> getTweets(); } </source>