diff --git a/.gitignore b/.gitignore index 216927c6..1dd9e71f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ *.properties .DS_Store +*.txt *.class *.jar *.war diff --git a/Misha100896/pom.xml b/Misha100896/pom.xml new file mode 100644 index 00000000..63b1167a --- /dev/null +++ b/Misha100896/pom.xml @@ -0,0 +1,52 @@ + + + 4.0.0 + + ru.fizteh.fivt.students + parent + 1.0-SNAPSHOT + + ru.fizteh.fivt.students + Misha100896 + 1.0-SNAPSHOT + Misha100896 + http://maven.apache.org + + UTF-8 + + + + junit + junit + 3.8.1 + test + + + org.twitter4j + twitter4j-core + [4.0,) + + + org.twitter4j + twitter4j-stream + 4.0.4 + + + com.beust + jcommander + 1.48 + + + com.google.maps + google-maps-services + 0.1.1 + + + junit + junit + 4.12 + test + + + diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/ClassConverter.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/ClassConverter.java new file mode 100644 index 00000000..2f0e8b7e --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/ClassConverter.java @@ -0,0 +1,38 @@ +package ru.fizteh.fivt.students.miniorm; + +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + + +public class + ClassConverter { + private static Map classes; + static { + classes = new HashMap<>(); + classes.put(Integer.class, "INTEGER"); + classes.put(Boolean.class, "BOOLEAN"); + classes.put(Byte.class, "TINYINT"); + classes.put(Short.class, "SMALLINT"); + classes.put(Long.class, "BIGINT"); + classes.put(Double.class, "DOUBLE"); + classes.put(Float.class, "FLOAT"); + classes.put(Time.class, "TIME"); + classes.put(Date.class, "DATE"); + classes.put(Timestamp.class, "TIMESTAMP"); + classes.put(Character.class, "CHAR"); + classes.put(String.class, "CLOB"); + classes.put(UUID.class, "UUID"); + } + + public static String convert(final Class currClass) { + if (classes.containsKey(currClass)) { + return classes.get(currClass); + } + return "OTHER"; + } + +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/DatabaseService.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/DatabaseService.java new file mode 100644 index 00000000..bbe64f14 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/DatabaseService.java @@ -0,0 +1,236 @@ +package ru.fizteh.fivt.students.miniorm; + +import com.google.common.base.Caseformat; +import ru.fizteh.fivt.students.miniorm.annotations.Column; +import ru.fizteh.fivt.students.miniorm.annotations.PrimaryKey; +import ru.fizteh.fivt.students.miniorm.annotations.Table; +import ru.fizteh.fivt.students.miniorm.exception.HandlerOfException; + +import javax.management.OperationsException; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +public class DatabaseService { + + private Connection connection = null; + private Statement statement = null; + private ResultSet resultSet = null; + private Field primaryKey = null; + private List columns = null; + private Field[] fields; + private String[] namesOfColumns; + private Class tableClass = null; + private String tableName = ""; + private int primaryKeyFieldNumber = -1; + + private boolean hasTableYet = false; + + DatabaseService(final Class elementClass) throws ClassNotFoundException, + SQLException, InstantiationException, IllegalAccessException { + + Class.forName("org.h2.Driver").newInstance(); + //путь к файлу с БД, соединение с драйверами БД + connection = DriverManager.getConnection("jdbc:h2:~/test", "test", "test"); + statement = connection.createStatement(); + + columns = new ArrayList<>(); + tableClass = elementClass; + Table table = tableClass.getAnnotation(Table.class); + if (table == null) { + throw new IllegalArgumentException("Class should be annotated with Table"); + } + tableName = table.name(); + if (tableName.equals("")) { + tableName = "MY_TABLE"; + } + int i = 0; + for (Field elem : tableClass.getDeclaredFields()) { + if (elem.getAnnotation(Column.class) != null) { + columns.add(elem); + } + if (elem.getAnnotation(PrimaryKey.class) != null) { + if (elem.getAnnotation(Column.class) == null) { + throw new IllegalArgumentException("Not all fields are columns"); + } + if (primaryKey != null) { + throw new IllegalArgumentException("Not one primary Key"); + } + primaryKey = elem; + primaryKeyFieldNumber = i; + } + ++i; + } + + resultSet = connection.getMetaData().getTables(null, null, + CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_UNDERSCORE, tableName), null); + resultSet.next(); + } + public final T queryById(final K id) throws OperationsException, + SQLException, IllegalAccessException, InstantiationException { + if (!hasTableYet) { + throw new OperationsException("Для данного запроа необходимо создать таблицу"); + } + if (primaryKey == null) { + throw new OperationsException("Должен суущестовать первичный ключ"); + } + + StringBuilder newRequest = new StringBuilder(); + newRequest.append("SELECT * FROM ").append(tableName).append(" WHERE ") + .append(columns.get(primaryKeyFieldNumber).getAnnotation(Column.class) + .name()).append(" = ").append(id.toString()); + resultSet = statement.executeQuery(newRequest.toString()); + List list = new ArrayList<>(); + while (resultSet.next()) { + T item = tableClass.newInstance(); + for (Field field: columns) { + if (field.getType().equals(Integer.class)) { + field.set(item, resultSet.getInt(field.getAnnotation(Column.class).name())); + } + if (field.getType().equals(String.class)) { + field.set(item, resultSet.getString(field.getAnnotation(Column.class).name())); + } + } + list.add(item); + } + if (list.size() == 0) { + return null; + } + if (list.size() > 1) { + throw new OperationsException("Ошибка получения результата"); + } + return list.get(0); + } + + final List queryForAll() throws OperationsException, SQLException, IllegalAccessException, + InstantiationException { + + if (!hasTableYet) { + throw new OperationsException("Для данного запроа необходимо создать таблицу"); + } + if (primaryKey == null) { + throw new OperationsException("Должен суущестовать первичный ключ"); + } + StringBuilder newRequest = new StringBuilder(); + newRequest.append("SELECT * FROM ").append(tableName); + resultSet = statement.executeQuery(newRequest.toString()); + List list = new ArrayList<>(); + while (resultSet.next()) { + T item = tableClass.newInstance(); + for (Field field: columns) { + if (field.getType().equals(Integer.class)) { + field.set(item, resultSet.getInt(field.getAnnotation(Column.class).name())); + } + if (field.getType().equals(String.class)) { + field.set(item, resultSet.getString(field.getAnnotation(Column.class).name())); + } + } + list.add(item); + } + return list; + } + + final void insert(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder(); + newRequest.append("INSERT INTO ").append(tableName).append(" VALUES("); + boolean first = true; + for (Field field:columns) { + if (!first) { + newRequest.append(", "); + } else { + first = false; + } + newRequest.append("?"); + } + newRequest.append(")"); + //System.out.println(newRequest); + PreparedStatement preparedStatement = connection.prepareStatement(newRequest.toString()); + + for (int i = 0; i < columns.size(); i++) { + try { + preparedStatement.setObject(i + 1, columns.get(i).get(key)); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + } + //System.out.println(preparedStatement.toString()); + preparedStatement.execute(); + + } + + final void update(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder().append("UPDATE ").append(tableName).append(" SET "); + for (int i = 0; i < columns.size(); ++i) { + if (i != 0) { + newRequest.append(", "); + } + newRequest.append(columns.get(i).getAnnotation(Column.class).name()).append(" = ?"); + } + + newRequest.append(" WHERE ").append(columns.get(primaryKeyFieldNumber).getAnnotation(Column.class).name()) + .append(" = ?"); + PreparedStatement prepareStatement = connection.prepareStatement(newRequest.toString()); + for (int i = 0; i < columns.size(); i++) { + try { + prepareStatement.setObject(1, columns.get(i).get(key)); + prepareStatement.setObject(2, columns.get(primaryKeyFieldNumber).get(key)); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + prepareStatement.execute(); + } + + + + } + + + final void delete(final T key) throws SQLException { + StringBuilder newRequest = new StringBuilder(); + newRequest.append("DELETE FROM ").append(tableName).append(columns.get(primaryKeyFieldNumber) + .getAnnotation(Column.class).name()).append(" = ").append("?"); + PreparedStatement preparedStatement = connection.prepareStatement(newRequest.toString()); + try { + preparedStatement.setObject(1, columns.get(primaryKeyFieldNumber).get(key)); + preparedStatement.execute(); + } catch (IllegalAccessException e) { + HandlerOfException.handler(e); + } + } + + final void createTable() throws OperationsException, SQLException { + if (hasTableYet) { + throw new OperationsException("Невозможно повторно создать таблицу"); + } + hasTableYet = true; + StringBuilder newRequest = new StringBuilder(); + newRequest.append("CREATE TABLE IF NOT EXISTS ").append(tableName).append(" ("); + int i = 0; + for (Field field : columns) { + //System.out.println(field.getType().toString()); + if (i != 0) { + newRequest.append(", "); + } + newRequest.append(field.getAnnotation(Column.class).name()).append(" "); + newRequest.append(ClassConverter.convert(columns.get(i).getType())).append(" "); + if (field.isAnnotationPresent(PrimaryKey.class)) { + newRequest.append("PRIMARY KEY"); + primaryKeyFieldNumber = i; + } + i++; + } + newRequest.append(") "); + //System.out.println(newRequest); + statement.execute(newRequest.toString()); + } + + final void dropTable() { + try { + statement.execute("DROP TABLE IF EXISTS " + tableName); + hasTableYet = false; + } catch (SQLException e) { + HandlerOfException.handler(e); + } + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Column.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Column.java new file mode 100644 index 00000000..8d660c90 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Column.java @@ -0,0 +1,12 @@ +package ru.fizteh.fivt.students.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.FIELD) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Column { + String name() default ""; +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/PrimaryKey.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/PrimaryKey.java new file mode 100644 index 00000000..ea0ffc98 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/PrimaryKey.java @@ -0,0 +1,11 @@ +package ru.fizteh.fivt.students.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.FIELD) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface PrimaryKey { +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Table.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Table.java new file mode 100644 index 00000000..01b6bb27 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/annotations/Table.java @@ -0,0 +1,12 @@ +package ru.fizteh.fivt.students.miniorm.annotations; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Target(value = ElementType.TYPE) +@Retention(value = RetentionPolicy.RUNTIME) +public @interface Table { + String name() default ""; +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/exception/HandlerOfException.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/exception/HandlerOfException.java new file mode 100644 index 00000000..f50d02ba --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/miniorm/exception/HandlerOfException.java @@ -0,0 +1,23 @@ +package ru.fizteh.fivt.students.miniorm.exception; + +public class HandlerOfException { + static final String USER_MOD = "user"; + + public static void handler(final String message, final Throwable cause) { + System.err.println(message + ". " + cause.getMessage()); + System.exit(1); + } + public static void handler(final Throwable cause) { + System.err.println(cause.getMessage()); + System.exit(1); + } + + public static void handler(final Throwable cause, final String mod) { + if (mod.equals(USER_MOD)) { + System.err.println(cause.getMessage()); + } else { + System.err.println(cause.getMessage()); + System.exit(1); + } + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/Configuration.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/Configuration.java new file mode 100644 index 00000000..e5a9a5d2 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/Configuration.java @@ -0,0 +1,50 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.beust.jcommander.Parameter; + +public class Configuration { + static final int DEFAULT_LIMIT = 10; + + @Parameter(names = { "--query", "-q"}, description = "Find query") + private String query = null; + + @Parameter(names = {"--place", "-p"}, description = "Search place") + private String place = null; + + @Parameter(names = {"--stream", "-s"}, description = "Stream") + private boolean stream = false; + + @Parameter(names = {"--hideRetweets"}, description = "Hide retweets") + private boolean hideRetweets = false; + + @Parameter(names = {"--limit", "-l"}, description = "Limit tweets") + private int limitTweets = DEFAULT_LIMIT; + + @Parameter(names = {"--help", "-h"}, description = "Help for you") + private boolean help = false; + + public String getQuery() { + return query; + } + + public String getPlace() { + return place; + } + + public boolean isStream() { + return stream; + } + + public boolean isHideRetweets() { + return hideRetweets; + } + + public int getLimitTweets() { + return limitTweets; + } + + public boolean isHelp() { + return help; + } + +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/HaveConnection.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/HaveConnection.java new file mode 100644 index 00000000..0c65be0c --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/HaveConnection.java @@ -0,0 +1,22 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +public class HaveConnection { + + public static boolean netIsAvailable(String checkHost) { + try { + final URL url = new URL(checkHost); + final URLConnection conn = url.openConnection(); + conn.connect(); + return true; + } catch (MalformedURLException exception) { + throw new RuntimeException(exception); + } catch (IOException exception) { + return false; + } + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocation.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocation.java new file mode 100644 index 00000000..3d0a2473 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocation.java @@ -0,0 +1,70 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.google.maps.GeoApiContext; +import com.google.maps.GeocodingApi; +import com.google.maps.model.Bounds; +import com.google.maps.model.GeocodingResult; +import com.google.maps.model.LatLng; + +import java.io.*; +import java.util.Scanner; +import static java.lang.Math.*; + +public class MyGeoLocation { + + private static final double RADIUS_OF_EARTH = 6371; + private static final double DEGREES_IN_SEMICIRCLE = 180; + + private GeocodingResult geocodingResults; + private double radius; + + public void findPlace(String place) { + + String apiKey = null; + + try { + File keyFile = new File("googlemaps.properties"); + apiKey = new Scanner(keyFile).useDelimiter("\\Z").next(); + } catch (FileNotFoundException exception) { + } + + GeoApiContext context = new GeoApiContext().setApiKey(apiKey); + + try { + geocodingResults = GeocodingApi.geocode(context, place).await()[0]; + } catch (Exception exception) { + } + + radius = calculateRadius(); + + } + + private double calculateRadius() { + LatLng point1 = geocodingResults.geometry.bounds.northeast; + LatLng point2 = geocodingResults.geometry.bounds.southwest; + double rad = DEGREES_IN_SEMICIRCLE / PI; + + double x1 = point1.lat / rad; + double y1 = point1.lng / rad; + double x2 = point2.lat / rad; + double y2 = point2.lng / rad; + + double t1 = cos(x1) * cos(y1) * cos(x2) * cos(y2); + double t2 = cos(x1) * sin(y1) * cos(x2) * sin(y2); + double t3 = sin(x1) * sin(x2); + + return RADIUS_OF_EARTH * acos(t1 + t2 + t3); + } + + public LatLng getLocation() { + return geocodingResults.geometry.location; + } + + public double getRadius() { + return radius; + } + + public final Bounds getBounds() { + return geocodingResults.geometry.bounds; + } +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/PrintTweet.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/PrintTweet.java new file mode 100644 index 00000000..fccfabef --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/PrintTweet.java @@ -0,0 +1,60 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import twitter4j.Status; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +public class PrintTweet { + + private static final String SEPARATE = + "------------------------------------------------------"; + + public static String printTweet(Status tweet) { + String result = "@" + tweet.getUser().getName() + ": "; + if (tweet.isRetweet()) { + result += "retweeted @" + tweet.getRetweetedStatus().getUser().getName() + + ": " + tweet.getText(); + } else { + result += tweet.getText() + "(" + tweet.getRetweetCount() + "retweets)"; + } + + result += '\n' + SEPARATE + '\n'; + return result; + } + + public static String printTime(Date date) { + + String result = "["; + + LocalDateTime currentTime = LocalDateTime.now(); + LocalDateTime tweetTime = date.toInstant() + .atZone(ZoneId.systemDefault()).toLocalDateTime(); + + if (ChronoUnit.MINUTES.between(tweetTime, currentTime) < 2) { + result += "только что"; + } else { + if (ChronoUnit.HOURS.between(tweetTime, currentTime) < 1) { + result += ChronoUnit.MINUTES.between(tweetTime, currentTime) + + " минут назад"; + } else { + if (ChronoUnit.DAYS.between(tweetTime, currentTime) < 1) { + result += ChronoUnit.HOURS.between(tweetTime, currentTime) + + " чаов назад"; + } else { + if (ChronoUnit.DAYS.between(tweetTime, currentTime) == 1) { + result += "вчера"; + } else { + result += ChronoUnit.DAYS.between(tweetTime, currentTime) + + " дней назад"; + } + } + } + } + + result += "] "; + return result; + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/TwitterStream.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/TwitterStream.java new file mode 100644 index 00000000..9a438cdc --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/moduletests/library/TwitterStream.java @@ -0,0 +1,119 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.beust.jcommander.JCommander; +import twitter4j.*; + +import java.util.List; + +public class TwitterStream { + + private static final int TWEET_DELAY = 1000; + + private Configuration configuration; + + public TwitterStream(String[] args) { + configuration = new Configuration(); + JCommander jCommander = new JCommander(configuration, args); + if (configuration.isHelp()) { + jCommander.usage(); + } + } + + public static void runStream(Configuration configuration) { + + if (!HaveConnection.netIsAvailable("http://api.twitter.com")) { + System.err.println("No connection"); + System.exit(1); + } + + twitter4j.TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + StatusListener statusListener = new StatusAdapter() { + + @Override + public void onStatus(Status tweet) { + if (!configuration.isHideRetweets() || !tweet.isRetweet()) { + + System.out.print(PrintTweet.printTweet(tweet)); + + try { + Thread.sleep(TWEET_DELAY); + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + System.err.println("Thread error: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + } + } + + @Override + public void onException(Exception exception) { + System.err.println("Stream error: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + }; + + twitterStream.addListener(statusListener); + FilterQuery filterQuery = new FilterQuery(); + filterQuery.track(configuration.getQuery()); + if (configuration.getPlace() != null) { + + MyGeoLocation findPlace = new MyGeoLocation();; + findPlace.findPlace(configuration.getPlace()); + double[][] bounds = {{findPlace.getBounds().southwest.lng, + findPlace.getBounds().southwest.lat}, + {findPlace.getBounds().northeast.lng, + findPlace.getBounds().northeast.lat}}; + filterQuery.locations(bounds); + } + twitterStream.filter(filterQuery); + } + + public static void findTweets(Configuration configuration) { + + if (!HaveConnection.netIsAvailable("http://api.twitter.com")) { + System.err.println("No connection"); + System.exit(1); + } + + Twitter twitter = new TwitterFactory().getInstance(); + Query query = new Query(); + query.setQuery(configuration.getQuery()); + query.setCount(configuration.getLimitTweets()); + + if (configuration.getPlace() != null) { + MyGeoLocation googleFindPlace = new MyGeoLocation(); + googleFindPlace.findPlace(configuration.getPlace()); + GeoLocation geoLocation; + geoLocation = new GeoLocation(googleFindPlace.getLocation().lat, + googleFindPlace.getLocation().lng); + query.setGeoCode(geoLocation, googleFindPlace.getRadius(), Query.KILOMETERS); + + } + + try { + List tweets = twitter.search(query).getTweets(); + for (Status tweet: tweets) { + System.out.print(PrintTweet.printTime(tweet.getCreatedAt())); + System.out.println(PrintTweet.printTweet(tweet)); + } + } catch (TwitterException exception) { + System.err.println("FindTweetsError: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + + } + + public static void main(String[] args) { + TwitterStream twitterStream = new TwitterStream(args); + if (twitterStream.configuration != null) { + if (twitterStream.configuration.isStream()) { + runStream(twitterStream.configuration); + } else { + findTweets(twitterStream.configuration); + } + } + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/BlockingQueue.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/BlockingQueue.java new file mode 100644 index 00000000..0dbb4ea3 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/BlockingQueue.java @@ -0,0 +1,109 @@ +package ru.fizteh.fivt.students.threads; + +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Condition; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; + +public class BlockingQueue { + private Queue queue; + private int capacity; + + private Lock queueLock = new ReentrantLock(); + private Condition queueFull = queueLock.newCondition(); + private Condition queueEmpty = queueLock.newCondition(); + + BlockingQueue(int size) { + queue = new LinkedList(); + capacity = size; + } + + public final void offer(List list) { + queueLock.lock(); + try { + while (queue.size() + list.size() > capacity) { + queueFull.await(); + } + queue.addAll(list); + } catch (InterruptedException exception) { + System.out.println("Thread interrupted" + exception.toString()); + exception.printStackTrace(); + } finally { + queueLock.unlock(); + } + queueEmpty.signalAll(); + } + + public final List take(int amount) { + queueLock.lock(); + List answer = new LinkedList<>(); + try { + while (queue.size() < amount) { + queueEmpty.await(); + } + for (int i = 0; i < amount; i++) { + answer.add(queue.remove()); + } + } catch (InterruptedException exception) { + System.out.println("Thread interrupted" + exception.toString()); + exception.printStackTrace(); + } finally { + queueLock.unlock(); + } + queueFull.signalAll(); + return answer; + } + + public final void offer(List list, long timeout) { + queueLock.lock(); + try { + long lastCheckTime = System.currentTimeMillis(); + long timeToWait = timeout; + while (queue.size() + list.size() > capacity) { + long currentTime = System.currentTimeMillis(); + timeToWait -= (currentTime - lastCheckTime); + lastCheckTime = currentTime; + queueFull.await(timeToWait, TimeUnit.MILLISECONDS); + } + if (timeToWait > 0) { + queue.addAll(list); + } + } catch (InterruptedException exception) { + System.out.println("Thread interrupted"); + exception.printStackTrace(); + } finally { + queueLock.unlock(); + } + queueFull.signalAll(); + } + + public final List take(int amount, long timeout) { + queueLock.lock(); + List answer = new LinkedList<>(); + try { + long lastCheckTime = System.currentTimeMillis(); + long timeToWait = timeout; + while (queue.size() < amount) { + long currentTime = System.currentTimeMillis(); + timeToWait -= (currentTime - lastCheckTime); + lastCheckTime = currentTime; + queueEmpty.await(timeToWait, TimeUnit.MILLISECONDS); + } + if (timeToWait > 0) { + for (int i = 0; i < amount; i++) { + answer.add(queue.remove()); + } + } + } catch (InterruptedException exception) { + System.out.println("Thread interrupted"); + exception.printStackTrace(); + } finally { + queueLock.unlock(); + } + queueFull.signalAll(); + return answer; + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsCounter.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsCounter.java new file mode 100644 index 00000000..d85a86ae --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsCounter.java @@ -0,0 +1,53 @@ +package ru.fizteh.fivt.students.threads; + +public class ThreadsCounter { + private static Object monitor = new Object(); + private static volatile int activeThread = 0; + + public static class CounterRunner extends Thread { + + private int threadID, countThreads; + + CounterRunner(int threadNumber, int totalThreads) { + threadID = threadNumber; + countThreads = totalThreads; + } + + @Override + public final void run() { + try { + while (true) { + synchronized (monitor) { + if (threadID == activeThread) { + System.out.println("Thread-" + (threadID + 1)); + activeThread++; + activeThread %= countThreads; + monitor.notifyAll(); + } else { + monitor.wait(); + } + } + } + } catch (InterruptedException e) { + System.out.println("We were interrupted"); + e.printStackTrace(); + System.exit(1); + } + } + } + + public static void main(String[] args) { + int totalThreads = 0; + try { + totalThreads = Integer.parseInt(args[0]); + + } catch (Exception exception) { + System.out.println("Wrong input arguments" + exception.toString()); + System.exit(1); + } + for (int i = 0; i < totalThreads; i++) { + CounterRunner thread = new CounterRunner(i, totalThreads); + thread.start(); + } + } +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsRollcall.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsRollcall.java new file mode 100644 index 00000000..e9eccab2 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/threads/ThreadsRollcall.java @@ -0,0 +1,73 @@ +package ru.fizteh.fivt.students.threads; + +import java.util.concurrent.CyclicBarrier; +import java.util.concurrent.BrokenBarrierException; +import java.util.Random; + +public class ThreadsRollcall { + + private static CyclicBarrier threadsStarted; + private static CyclicBarrier threadsCompleted; + private static volatile boolean allThreadsReady = true; + private static final int RANDOM_BORDER = 10; + + private static class RollcallRunner extends Thread { + private Random generator = new Random(); + + @Override + public final void run() { + try { + while (true) { + threadsStarted.await(); + int randomSeed = generator.nextInt(RANDOM_BORDER); + if (randomSeed <= 1) { + allThreadsReady = false; + System.out.println("No"); + } else { + System.out.println("Yes"); + } + threadsCompleted.await(); + } + } catch (InterruptedException | BrokenBarrierException exception) { + System.out.println("Something went wrong " + exception.toString()); + System.out.println(exception.getMessage()); + System.exit(1); + } + } + } + + public static void main(String[] args) { + int countThreads = 0; + try { + countThreads = Integer.parseInt(args[0]); + } catch (Exception exception) { + System.out.println("Wrong input arguments" + exception.toString()); + System.exit(1); + } + + threadsStarted = new CyclicBarrier(countThreads + 1); + threadsCompleted = new CyclicBarrier(countThreads + 1); + + for (int i = 0; i < countThreads; i++) { + RollcallRunner thread = new RollcallRunner(); + thread.start(); + } + + while (true) { + allThreadsReady = true; + System.out.println("Are you ready?"); + try { + threadsStarted.await(); + threadsStarted.reset(); + threadsCompleted.await(); + threadsCompleted.reset(); + } catch (InterruptedException | BrokenBarrierException exception) { + exception.printStackTrace(); + System.exit(1); + } + if (allThreadsReady) { + System.exit(0); + } + } + } +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/Configuration.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/Configuration.java new file mode 100644 index 00000000..8a019a9a --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/Configuration.java @@ -0,0 +1,50 @@ +package ru.fizteh.fivt.students.twitterstream; + +import com.beust.jcommander.Parameter; + +public class Configuration { + static final int DEFAULT_LIMIT = 10; + + @Parameter(names = { "--query", "-q"}, description = "Find query") + private String query = null; + + @Parameter(names = {"--place", "-p"}, description = "Search place") + private String place = null; + + @Parameter(names = {"--stream", "-s"}, description = "Stream") + private boolean stream = false; + + @Parameter(names = {"--hideRetweets"}, description = "Hide retweets") + private boolean hideRetweets = false; + + @Parameter(names = {"--limit", "-l"}, description = "Limit tweets") + private int limitTweets = DEFAULT_LIMIT; + + @Parameter(names = {"--help", "-h"}, description = "Help for you") + private boolean help = false; + + public String getQuery() { + return query; + } + + public String getPlace() { + return place; + } + + public boolean isStream() { + return stream; + } + + public boolean isHideRetweets() { + return hideRetweets; + } + + public int getLimitTweets() { + return limitTweets; + } + + public boolean isHelp() { + return help; + } + +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/HaveConnection.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/HaveConnection.java new file mode 100644 index 00000000..cc28d11c --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/HaveConnection.java @@ -0,0 +1,22 @@ +package ru.fizteh.fivt.students.twitterstream; + +import java.io.IOException; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLConnection; + +public class HaveConnection { + + public static boolean netIsAvailable(String checkHost) { + try { + final URL url = new URL(checkHost); + final URLConnection conn = url.openConnection(); + conn.connect(); + return true; + } catch (MalformedURLException exception) { + throw new RuntimeException(exception); + } catch (IOException exception) { + return false; + } + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/MyGeoLocation.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/MyGeoLocation.java new file mode 100644 index 00000000..9c7785fe --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/MyGeoLocation.java @@ -0,0 +1,76 @@ +package ru.fizteh.fivt.students.twitterstream; + +import com.google.maps.GeoApiContext; +import com.google.maps.GeocodingApi; +import com.google.maps.model.Bounds; +import com.google.maps.model.GeocodingResult; +import com.google.maps.model.LatLng; + +import java.io.*; +import java.util.Scanner; +import static java.lang.Math.*; + +public class MyGeoLocation { + + private static final double RADIUS_OF_EARTH = 6371; + private static final double DEGREES_IN_SEMICIRCLE = 180; + + private GeocodingResult geocodingResults; + private double radius; + + MyGeoLocation(String place) { + + String apiKey = null; + + try { + File keyFile = new File("googlemaps.properties"); + apiKey = new Scanner(keyFile).useDelimiter("\\Z").next(); + } catch (FileNotFoundException exception) { + System.err.println("Can't find or read googleApiKey " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + + GeoApiContext context = new GeoApiContext().setApiKey(apiKey); + + try { + geocodingResults = GeocodingApi.geocode(context, place).await()[0]; + } catch (Exception exception) { + System.err.println("Break in get geocoding: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + + radius = calculateRadius(); + + } + + private double calculateRadius() { + LatLng point1 = geocodingResults.geometry.bounds.northeast; + LatLng point2 = geocodingResults.geometry.bounds.southwest; + double rad = DEGREES_IN_SEMICIRCLE / PI; + + double x1 = point1.lat / rad; + double y1 = point1.lng / rad; + double x2 = point2.lat / rad; + double y2 = point2.lng / rad; + + double t1 = cos(x1) * cos(y1) * cos(x2) * cos(y2); + double t2 = cos(x1) * sin(y1) * cos(x2) * sin(y2); + double t3 = sin(x1) * sin(x2); + + return RADIUS_OF_EARTH * acos(t1 + t2 + t3); + } + + public LatLng getLocation() { + return geocodingResults.geometry.location; + } + + public double getRadius() { + return radius; + } + + public final Bounds getBounds() { + return geocodingResults.geometry.bounds; + } +} \ No newline at end of file diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/PrintTweet.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/PrintTweet.java new file mode 100644 index 00000000..4e998161 --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/PrintTweet.java @@ -0,0 +1,59 @@ +package ru.fizteh.fivt.students.twitterstream; + +import twitter4j.Status; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +public class PrintTweet { + + private static final String SEPARATE = + "------------------------------------------------------"; + + public static void printTweet(Status tweet) { + + System.out.print("@" + tweet.getUser().getName() + ": "); + if (tweet.isRetweet()) { + System.out.println("retweeted @" + tweet.getRetweetedStatus().getUser().getName() + + ": " + tweet.getText()); + } else { + System.out.println(tweet.getText() + "(" + tweet.getRetweetCount() + "retweets)"); + } + + System.out.println(SEPARATE); + } + + public static void printTime(Date date) { + + System.out.print("["); + + LocalDateTime currentTime = LocalDateTime.now(); + LocalDateTime tweetTime = date.toInstant() + .atZone(ZoneId.systemDefault()).toLocalDateTime(); + + if (ChronoUnit.MINUTES.between(tweetTime, currentTime) < 2) { + System.out.print("только что"); + } else { + if (ChronoUnit.HOURS.between(tweetTime, currentTime) < 1) { + System.out.print(ChronoUnit.MINUTES.between(tweetTime, currentTime) + + " минут назад"); + } else { + if (ChronoUnit.DAYS.between(tweetTime, currentTime) < 1) { + System.out.print(ChronoUnit.HOURS.between(tweetTime, currentTime) + + " чаов назад"); + } else { + if (ChronoUnit.DAYS.between(tweetTime, currentTime) == 1) { + System.out.print("вчера"); + } else { + System.out.print(ChronoUnit.DAYS.between(tweetTime, currentTime) + + " дней назад"); + } + } + } + } + + System.out.print("] "); + } +} diff --git a/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/TwitterStream.java b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/TwitterStream.java new file mode 100644 index 00000000..935314cb --- /dev/null +++ b/Misha100896/src/main/java/ru/fizteh/fivt/students/twitterstream/TwitterStream.java @@ -0,0 +1,119 @@ +package ru.fizteh.fivt.students.twitterstream; + +import com.beust.jcommander.JCommander; +import twitter4j.*; + +import java.util.List; + +public class TwitterStream { + + private static final int TWEET_DELAY = 1000; + + private Configuration configuration; + + public TwitterStream(String[] args) { + configuration = new Configuration(); + JCommander jCommander = new JCommander(configuration, args); + if (configuration.isHelp()) { + jCommander.usage(); + } + } + + public static void runStream(Configuration configuration) { + + if (!HaveConnection.netIsAvailable("http://api.twitter.com")) { + System.err.println("No connection"); + System.exit(1); + } + + twitter4j.TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + StatusListener statusListener = new StatusAdapter() { + + @Override + public void onStatus(Status tweet) { + if (!configuration.isHideRetweets() || !tweet.isRetweet()) { + + PrintTweet.printTweet(tweet); + + try { + Thread.sleep(TWEET_DELAY); + } catch (InterruptedException exception) { + Thread.currentThread().interrupt(); + System.err.println("Thread error: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + } + } + + @Override + public void onException(Exception exception) { + System.err.println("Stream error: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + }; + + twitterStream.addListener(statusListener); + FilterQuery filterQuery = new FilterQuery(); + filterQuery.track(configuration.getQuery()); + if (configuration.getPlace() != null) { + + MyGeoLocation findPlace; + findPlace = new MyGeoLocation((configuration.getPlace())); + double[][] bounds = {{findPlace.getBounds().southwest.lng, + findPlace.getBounds().southwest.lat}, + {findPlace.getBounds().northeast.lng, + findPlace.getBounds().northeast.lat}}; + filterQuery.locations(bounds); + } + twitterStream.filter(filterQuery); + } + + public static void findTweets(Configuration configuration) { + + if (!HaveConnection.netIsAvailable("http://api.twitter.com")) { + System.err.println("No connection"); + System.exit(1); + } + + Twitter twitter = new TwitterFactory().getInstance(); + Query query = new Query(); + query.setQuery(configuration.getQuery()); + query.setCount(configuration.getLimitTweets()); + + if (configuration.getPlace() != null) { + MyGeoLocation googleFindPlace; + googleFindPlace = new MyGeoLocation(configuration.getPlace()); + GeoLocation geoLocation; + geoLocation = new GeoLocation(googleFindPlace.getLocation().lat, + googleFindPlace.getLocation().lng); + query.setGeoCode(geoLocation, googleFindPlace.getRadius(), Query.KILOMETERS); + + } + + try { + List tweets = twitter.search(query).getTweets(); + for (Status tweet: tweets) { + PrintTweet.printTime(tweet.getCreatedAt()); + PrintTweet.printTweet(tweet); + } + } catch (TwitterException exception) { + System.err.println("FindTweetsError: " + exception.toString()); + exception.printStackTrace(System.err); + System.exit(1); + } + + } + + public static void main(String[] args) { + TwitterStream twitterStream = new TwitterStream(args); + if (twitterStream.configuration != null) { + if (twitterStream.configuration.isStream()) { + runStream(twitterStream.configuration); + } else { + findTweets(twitterStream.configuration); + } + } + } +} diff --git a/Misha100896/src/test/java/ru/fizteh/fivt/students/AppTest.java b/Misha100896/src/test/java/ru/fizteh/fivt/students/AppTest.java new file mode 100644 index 00000000..5e698088 --- /dev/null +++ b/Misha100896/src/test/java/ru/fizteh/fivt/students/AppTest.java @@ -0,0 +1,38 @@ +package ru.fizteh.fivt.students; + +import junit.framework.Test; +import junit.framework.TestCase; +import junit.framework.TestSuite; + +/** + * Unit test for simple App. + */ +public class AppTest + extends TestCase +{ + /** + * Create the test case + * + * @param testName name of the test case + */ + public AppTest( String testName ) + { + super( testName ); + } + + /** + * @return the suite of tests being tested + */ + public static Test suite() + { + return new TestSuite( AppTest.class ); + } + + /** + * Rigourous Test :-) + */ + public void testApp() + { + assertTrue( true ); + } +} diff --git a/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/ConfigurationTest.java b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/ConfigurationTest.java new file mode 100644 index 00000000..632d94cf --- /dev/null +++ b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/ConfigurationTest.java @@ -0,0 +1,57 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.beust.jcommander.JCommander; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(DataProviderRunner.class) +public class ConfigurationTest extends TestCase { + + Configuration configuration = new Configuration(); + JCommander jCommander = new JCommander(configuration); + + @DataProvider + public static Object[][] parseArgument() { + return new Object[][] { + { + "-s -q \"anime\" --hideRetweets", + "anime", + null, + true, + true, + 10, + false + }, + + { + "-l 15 -p \"Moscow\" -q \"naruto\"", + "naruto", + "Moscow", + false, + false, + 15, + false + } + }; + } + + @Test + @UseDataProvider("parseArgument") + public void testParseArgument(String argumentString, String expectedQuery, + String expectedPlace, boolean expectedStream, + boolean expectedHideRetweets, int expectedLimitTweets, + boolean expectedHelp) { + + jCommander.parse(argumentString.split(" ")); + assertEquals(configuration.getQuery(), expectedQuery); + assertEquals(configuration.getPlace(), expectedPlace); + assertEquals(configuration.isStream(), expectedStream); + assertEquals(configuration.isHideRetweets(), expectedHideRetweets); + assertEquals(configuration.getLimitTweets(), expectedLimitTweets); + assertEquals(configuration.isHelp(), expectedHelp); + } +} diff --git a/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/HaveConnectionTest.java b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/HaveConnectionTest.java new file mode 100644 index 00000000..2f35cfe5 --- /dev/null +++ b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/HaveConnectionTest.java @@ -0,0 +1,39 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; + +@RunWith(DataProviderRunner.class) +public class HaveConnectionTest extends TestCase { + + HaveConnection haveConnection = new HaveConnection(); + + @DataProvider + public static Object[][] hostConnection() { + return new Object[][] { + { + "http://yandex.ru", + true + }, + { + "http://youtube.com", + true + }, + { + "http://misha100896.com", + false + } + }; + } + + @Test + @UseDataProvider("hostConnection") + public void testHostConnection(String host, boolean connection) { + + assertEquals(haveConnection.netIsAvailable(host), connection); + } +} \ No newline at end of file diff --git a/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocationTest.java b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocationTest.java new file mode 100644 index 00000000..c5c9bc09 --- /dev/null +++ b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/MyGeoLocationTest.java @@ -0,0 +1,49 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.google.maps.model.LatLng; +import com.tngtech.java.junit.dataprovider.DataProvider; +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import com.tngtech.java.junit.dataprovider.UseDataProvider; +import junit.framework.TestCase; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static java.lang.Math.abs; + +@RunWith(DataProviderRunner.class) +public class MyGeoLocationTest extends TestCase { + + private static final double EPS = 1e-9; + + MyGeoLocation myGeoLocation = new MyGeoLocation(); + + @DataProvider + public static Object[][] locationLatLng() { + return new Object[][] { + { + "Rybinsk", + new LatLng(58.001714, 38.6495059), + new LatLng(58.1202071, 38.974287), + 23.207723459954384 + } + }; + } + + @Test + @UseDataProvider("locationLatLng") + public void testLocation(String city, LatLng p1, LatLng p2, double radius) { + myGeoLocation.findPlace(city); + + assert((myGeoLocation.getBounds().southwest.lat - p1.lat) + * (myGeoLocation.getBounds().southwest.lat - p1.lat) + + (myGeoLocation.getBounds().southwest.lng - p1.lng) + * (myGeoLocation.getBounds().southwest.lng - p1.lng) < EPS); + + assert((myGeoLocation.getBounds().northeast.lat - p2.lat) + * (myGeoLocation.getBounds().northeast.lat - p2.lat) + + (myGeoLocation.getBounds().northeast.lng - p2.lng) + * (myGeoLocation.getBounds().northeast.lng - p2.lng) < EPS); + + assert(abs(myGeoLocation.getRadius() - radius) < EPS); + } +} \ No newline at end of file diff --git a/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/PrintTweetTest.java b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/PrintTweetTest.java new file mode 100644 index 00000000..a322a3b4 --- /dev/null +++ b/Misha100896/src/test/java/ru/fizteh/fivt/students/moduletests/library/PrintTweetTest.java @@ -0,0 +1,79 @@ +package ru.fizteh.fivt.students.moduletests.library; + +import com.tngtech.java.junit.dataprovider.DataProviderRunner; +import junit.framework.TestCase; +import junit.framework.TestResult; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mock; +import org.junit.runner.RunWith; + +import twitter4j.Status; +import twitter4j.User; + +import java.sql.Time; +import java.util.Date; + +import static org.mockito.Mockito.*; + +@RunWith(DataProviderRunner.class) +public class PrintTweetTest extends TestCase { + + PrintTweet printTweet = new PrintTweet(); + + @Mock + private Status mockedStatus = mock(Status.class); + @Mock + private Status mockedRetweetedStatus = mock(Status.class); + @Mock + private User mockedUser = mock(User.class); + @Mock + private User mockedRetweetedUser = mock(User.class); + + @Before + public void setUp() { + + when(mockedStatus.getRetweetedStatus()). + thenReturn(mockedRetweetedStatus); + String tweetText = "Hello world!"; + + when(mockedStatus.getText()).thenReturn(tweetText); + when(mockedRetweetedStatus.getText()).thenReturn(tweetText); + + when(mockedStatus.getUser()).thenReturn(mockedUser); + when(mockedRetweetedStatus.getUser()).thenReturn(mockedRetweetedUser); + + when(mockedUser.getName()).thenReturn("Misha"); + when(mockedRetweetedUser.getName()).thenReturn("Semyon"); + + when(mockedStatus.isRetweet()).thenReturn(true); + when(mockedRetweetedStatus.isRetweet()).thenReturn(false); + + when(mockedStatus.isRetweeted()).thenReturn(false); + when(mockedRetweetedStatus.isRetweeted()).thenReturn(true); + + when(mockedRetweetedStatus.getRetweetCount()).thenReturn(2); + + } + + @Test + public void testPrintTweet() { + String expected = "@Misha: retweeted @Semyon: Hello world!\n------------------------------------------------------\n"; + assertEquals(printTweet.printTweet(mockedStatus), expected); + } + + @Test + public void testPrintTime() { + + //Test1 + String expected = "[только что] "; + Date date; + date = new Date(System.currentTimeMillis()); + assertEquals(printTweet.printTime(date), expected); + + //Test2 + date.setTime(date.getTime() - 1000 * 60 * 10 - 10); + expected = "[10 минут назад] "; + assertEquals(printTweet.printTime(date), expected); + } +}