From 3c9f495f2991c9b45ec6d868086f3f26a18595fb Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Fri, 9 Oct 2015 15:35:23 +0300 Subject: [PATCH 1/8] update Reverser --- .../students/annnvl/Reverser/Reverser.java | 5 +++-- projects/pom.xml | 18 ++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Reverser/Reverser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Reverser/Reverser.java index a26408d..a199d0c 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Reverser/Reverser.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Reverser/Reverser.java @@ -5,6 +5,7 @@ public static void main(String[] args) { String[] numbers = args[i].split("\\s+"); for (int j = numbers.length - 1; j >= 0; j--) System.out.print(numbers[j] + " "); - } + } } -} \ No newline at end of file +} + diff --git a/projects/pom.xml b/projects/pom.xml index 7b6298b..6bdd1bb 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -1,11 +1,12 @@ - + + 4.0.0 - ru.mipt.diht.students - parent - 1.0-SNAPSHOT - pom + ru.mipt.diht.students + parent + 1.0-SNAPSHOT + + pom fizteh-java-2015 https://github.com/KhurtinDN/fizteh-java-2015 @@ -28,8 +29,9 @@ dkhurtin - - + annnvl + + From 8e773c07fe39de571fa5b5c8d46aa133c99ce1fa Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Thu, 17 Dec 2015 01:56:42 +0300 Subject: [PATCH 2/8] =?UTF-8?q?=D0=92=D0=BD=D0=B5=D1=81=D0=B5=D0=BD=D1=8B?= =?UTF-8?q?=20=D0=BF=D0=BE=D0=BF=D1=80=D0=B0=D0=B2=D0=BA=D0=B8=20=D0=B2=20?= =?UTF-8?q?Threads?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Threads/BlockingQueue/BlockingQueue.java | 41 +++++++-------- .../annnvl/Threads/Counter/CountedThread.java | 23 +++++---- .../annnvl/Threads/Counter/Counter.java | 2 +- .../annnvl/Threads/RollCall/RollCall.java | 8 +-- .../Threads/RollCall/RollCallerThread.java | 50 +++++++++---------- .../java/ru/mipt/diht/students/AppTest.java | 38 -------------- 6 files changed, 60 insertions(+), 102 deletions(-) delete mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/AppTest.java diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java index cd12737..755762f 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java @@ -1,42 +1,42 @@ package ru.mipt.diht.students.annnvl.Threads.BlockingQueue; -import java.util.*; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; public class BlockingQueue { - private Queue data; private final int maxQueueSize; + private Queue data; - BlockingQueue(int size){ + BlockingQueue(int size) { maxQueueSize = size; data = new LinkedList(); } - public int size(){ + public int size() { return data.size(); } - synchronized public void offer(List e){ - while(data.size() + e.size() > maxQueueSize){ + synchronized public void offer(List e) { + while (data.size() + e.size() > maxQueueSize) { Thread.yield(); } data.addAll(e); } - synchronized public void offer(List e, long timeout){ - long lastBreathTime = System.currentTimeMillis(); - while((data.size() + e.size() > maxQueueSize) && timeout > 0){ + synchronized public void offer(List e, long timeout) { + timeout += System.currentTimeMillis(); + while ((data.size() + e.size() > maxQueueSize) && (timeout - System.currentTimeMillis()) > 0) { Thread.yield(); - long wakeupTime = System.currentTimeMillis(); - timeout -= (wakeupTime - lastBreathTime); - lastBreathTime = wakeupTime; } - if(timeout > 0){ + if (timeout > 0) { data.addAll(e); } } - synchronized List take(int n){ - while (data.size() < n){ + synchronized List take(int n) { + while (data.size() < n) { Thread.yield(); } List answer = new ArrayList(); @@ -46,15 +46,12 @@ synchronized List take(int n){ return answer; } - synchronized List take(int n, long timeout){ - long lastBreathTime = System.currentTimeMillis(); - while((data.size() < n) && timeout > 0){ + synchronized List take(int n, long timeout) { + timeout += System.currentTimeMillis(); + while ((data.size() < n) && (timeout - System.currentTimeMillis()) > 0) { Thread.yield(); - long wakeupTime = System.currentTimeMillis(); - timeout -= (wakeupTime - lastBreathTime); - lastBreathTime = wakeupTime; } - if(timeout > 0){ + if (timeout > 0) { List answer = new ArrayList(); for (int i = 0; i < n; i++) { answer.add(data.remove()); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java index b51ff93..adc255b 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java @@ -1,25 +1,26 @@ package ru.mipt.diht.students.annnvl.Threads.Counter; -public class CountedThread extends Thread{ +public class CountedThread extends Thread { private static int numberOfThreads; private static volatile int currentThread = 0; - public static void setNumberOfThreads(int num){ - numberOfThreads = num; - } - private final int myNumber; - CountedThread(int mynum){ + + CountedThread(int mynum) { myNumber = mynum; } + public static void setNumberOfThreads(int num) { + numberOfThreads = num; + } + @Override - public void run(){ - while (true){ - while (myNumber !=currentThread){ + public void run() { + while (true) { + while (myNumber != currentThread) { Thread.yield(); } - System.out.printf("Thread-%d\n", myNumber+1); - currentThread = (currentThread+1)%numberOfThreads; + System.out.println("Thread-" + (myNumber + 1) + "\n"); + currentThread = (currentThread + 1) % numberOfThreads; } } } diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/Counter.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/Counter.java index 7052826..c51271e 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/Counter.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/Counter.java @@ -2,7 +2,7 @@ public class Counter { public static void main(String[] args) { - if(args.length < 1){ + if (args.length < 1) { throw new IllegalArgumentException("Please type number of threads"); } int threads = Integer.parseInt(args[0]); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java index 0584f55..ca1e29c 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java @@ -2,7 +2,7 @@ public class RollCall { public static void main(String[] args) { - if(args.length < 1){ + if (args.length < 1) { throw new IllegalArgumentException("Please type number of threads"); } int threads = Integer.parseInt(args[0]); @@ -10,14 +10,14 @@ public static void main(String[] args) { for (int i = 0; i < threads; i++) { (new RollCallerThread()).start(); } - while(true){ + while (true) { RollCallerThread.makeEverybodyOk(); System.out.println("Are you ready?\n"); RollCallerThread.nextRollCall(); - while (!RollCallerThread.Everybodyasked()){ + while (!RollCallerThread.Everybodyasked()) { Thread.yield(); } - if(RollCallerThread.isEverybodyOk()){ + if (RollCallerThread.isEverybodyOk()) { RollCallerThread.Yes(); RollCallerThread.nextRollCall(); return; diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java index e304518..e27d596 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java @@ -2,59 +2,57 @@ import java.util.Random; -public class RollCallerThread extends Thread{ +public class RollCallerThread extends Thread { private static int numberOfThreads; - public static void setNumberOfThreads(int num){ - numberOfThreads = num; - } - private static volatile int asked = 0; - private Random rand; private static volatile int timesShouldBe = -1; //какой раз мы проводим опрос private static boolean Yes4all = false; private static boolean EverybodyOk = true; + private Random rand; + private int timesNum;//какой раз мы вызываем конкретный процесс + + RollCallerThread() { + rand = new Random(100); + timesNum = 0; + } - public static void Yes(){ + public static void setNumberOfThreads(int num) { + numberOfThreads = num; + } + + public static void Yes() { Yes4all = true; } - public static boolean isEverybodyOk(){ + public static boolean isEverybodyOk() { return EverybodyOk; } - public static void makeEverybodyOk(){ + public static void makeEverybodyOk() { EverybodyOk = true; } - public static void nextRollCall(){ + public static void nextRollCall() { timesShouldBe++; asked = 0; } - public static boolean Everybodyasked(){ + public static boolean Everybodyasked() { return (asked == numberOfThreads); } - private int timesNum;//какой раз мы вызываем конкретный процесс - - RollCallerThread(){ - rand = new Random(100); - timesNum = 0; - } - @Override - public void run(){ - while (true){ - synchronized (this){ - while(timesNum != timesShouldBe){ + public void run() { + while (true) { + synchronized (this) { + while (timesNum != timesShouldBe) { Thread.yield(); } - if (Yes4all){ + if (Yes4all) { return; } - timesNum ++; - if (rand.nextDouble() < 0.1) - { + timesNum++; + if (rand.nextDouble() < 0.1) { System.out.println("No\n"); EverybodyOk = false; } else { diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/AppTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/AppTest.java deleted file mode 100644 index 4bb8dd4..0000000 --- a/projects/annnvl/src/test/java/ru/mipt/diht/students/AppTest.java +++ /dev/null @@ -1,38 +0,0 @@ -package ru.mipt.diht.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 ); - } -} From c8117d49edf3e20b99e15fc1c7dbb97c66fbbad5 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Thu, 17 Dec 2015 02:23:52 +0300 Subject: [PATCH 3/8] style corrected --- .../Threads/BlockingQueue/BlockingQueue.java | 6 ++-- .../annnvl/Threads/Counter/CountedThread.java | 2 +- .../annnvl/Threads/RollCall/RollCall.java | 4 +-- .../Threads/RollCall/RollCallerThread.java | 28 ++++++++++--------- projects/pom.xml | 2 +- 5 files changed, 22 insertions(+), 20 deletions(-) diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java index 755762f..9306bf4 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java @@ -14,18 +14,18 @@ public class BlockingQueue { data = new LinkedList(); } - public int size() { + public final int size() { return data.size(); } - synchronized public void offer(List e) { + synchronized void offer(List e) { while (data.size() + e.size() > maxQueueSize) { Thread.yield(); } data.addAll(e); } - synchronized public void offer(List e, long timeout) { + synchronized void offer(List e, long timeout) { timeout += System.currentTimeMillis(); while ((data.size() + e.size() > maxQueueSize) && (timeout - System.currentTimeMillis()) > 0) { Thread.yield(); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java index adc255b..f74b91f 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java @@ -14,7 +14,7 @@ public static void setNumberOfThreads(int num) { } @Override - public void run() { + public final void run() { while (true) { while (myNumber != currentThread) { Thread.yield(); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java index ca1e29c..8ec4736 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java @@ -14,11 +14,11 @@ public static void main(String[] args) { RollCallerThread.makeEverybodyOk(); System.out.println("Are you ready?\n"); RollCallerThread.nextRollCall(); - while (!RollCallerThread.Everybodyasked()) { + while (!RollCallerThread.everybodyasked()) { Thread.yield(); } if (RollCallerThread.isEverybodyOk()) { - RollCallerThread.Yes(); + RollCallerThread.yes(); RollCallerThread.nextRollCall(); return; } diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java index e27d596..db2d7d9 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java @@ -3,16 +3,18 @@ import java.util.Random; public class RollCallerThread extends Thread { + private static final int HUNDREED = 100; + private static final double LOWERBOUND = 0.1; private static int numberOfThreads; private static volatile int asked = 0; private static volatile int timesShouldBe = -1; //какой раз мы проводим опрос - private static boolean Yes4all = false; - private static boolean EverybodyOk = true; + private static boolean yes4all = false; + private static boolean everybodyOk = true; private Random rand; - private int timesNum;//какой раз мы вызываем конкретный процесс + private int timesNum; //какой раз мы вызываем конкретный процесс RollCallerThread() { - rand = new Random(100); + rand = new Random(HUNDREED); timesNum = 0; } @@ -20,16 +22,16 @@ public static void setNumberOfThreads(int num) { numberOfThreads = num; } - public static void Yes() { - Yes4all = true; + public static void yes() { + yes4all = true; } public static boolean isEverybodyOk() { - return EverybodyOk; + return everybodyOk; } public static void makeEverybodyOk() { - EverybodyOk = true; + everybodyOk = true; } public static void nextRollCall() { @@ -37,24 +39,24 @@ public static void nextRollCall() { asked = 0; } - public static boolean Everybodyasked() { + public static boolean everybodyasked() { return (asked == numberOfThreads); } @Override - public void run() { + public final void run() { while (true) { synchronized (this) { while (timesNum != timesShouldBe) { Thread.yield(); } - if (Yes4all) { + if (yes4all) { return; } timesNum++; - if (rand.nextDouble() < 0.1) { + if (rand.nextDouble() < LOWERBOUND) { System.out.println("No\n"); - EverybodyOk = false; + everybodyOk = false; } else { System.out.println("Yes\n"); } diff --git a/projects/pom.xml b/projects/pom.xml index 6bdd1bb..c85f1f5 100644 --- a/projects/pom.xml +++ b/projects/pom.xml @@ -133,4 +133,4 @@ - + \ No newline at end of file From 8fa47008f02d0cdbcac5c8a1879fe9b4d54e28d9 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Sat, 19 Dec 2015 06:15:49 +0300 Subject: [PATCH 4/8] CQL+ex added, Threads fixed --- .../diht/students/annnvl/CQL/Aggregates.java | 60 +++++ .../students/annnvl/CQL/CollectionQuery.java | 107 ++++++++ .../diht/students/annnvl/CQL/Conditions.java | 37 +++ .../annnvl/CQL/OrderByConditions.java | 37 +++ .../diht/students/annnvl/CQL/Sources.java | 54 ++++ .../students/annnvl/CQL/impl/Aggregator.java | 8 + .../diht/students/annnvl/CQL/impl/Avg.java | 27 ++ .../diht/students/annnvl/CQL/impl/Count.java | 26 ++ .../students/annnvl/CQL/impl/FromStmt.java | 91 +++++++ .../diht/students/annnvl/CQL/impl/Max.java | 37 +++ .../diht/students/annnvl/CQL/impl/Min.java | 41 ++++ .../diht/students/annnvl/CQL/impl/Query.java | 13 + .../students/annnvl/CQL/impl/SelectStmt.java | 230 ++++++++++++++++++ .../diht/students/annnvl/CQL/impl/Tuple.java | 28 +++ .../students/annnvl/CQL/impl/UnionStmt.java | 119 +++++++++ .../Threads/BlockingQueue/BlockingQueue.java | 15 +- .../annnvl/Threads/Counter/CountedThread.java | 2 +- .../annnvl/Threads/RollCall/RollCall.java | 2 +- .../Threads/RollCall/RollCallerThread.java | 4 +- 19 files changed, 928 insertions(+), 10 deletions(-) create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Aggregates.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/CollectionQuery.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Conditions.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/OrderByConditions.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Sources.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Aggregator.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Avg.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Count.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/FromStmt.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Max.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Query.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/SelectStmt.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Tuple.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/UnionStmt.java diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Aggregates.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Aggregates.java new file mode 100644 index 0000000..7ea8271 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Aggregates.java @@ -0,0 +1,60 @@ +package ru.mipt.diht.students.annnvl.CQL; +/** + * Aggregate functions. + */ +import java.util.function.Function; +import ru.mipt.diht.students.annnvl.CQL.impl.Avg; +import ru.mipt.diht.students.annnvl.CQL.impl.Count; +import ru.mipt.diht.students.annnvl.CQL.impl.Max; +import ru.mipt.diht.students.annnvl.CQL.impl.Min; + +public class Aggregates { + + /** + * Maximum value for expression for elements of given collecdtion. + * + * @param expression + * @param + * @param + * @return + */ + public static > Function max(Function expression) { + return new Max<>(expression); + } + + /** + * Minimum value for expression for elements of given collecdtion. + * + * @param expression + * @param + * @param + * @return + */ + public static > Function min(Function expression) { + return new Min<>(expression); + } + + /** + * Number of items in source collection that turns this expression into not null. + * + * @param expression + * @param + * @return + */ + public static Function count(Function expression) { + return new Count<>(expression); + } + + + /** + * Average value for expression for elements of given collection. + * + * @param expression + * @param + * @return + */ + public static Function avg(Function expression) { + return new Avg<>(expression); + } + +} \ No newline at end of file diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/CollectionQuery.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/CollectionQuery.java new file mode 100644 index 0000000..8e4d161 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/CollectionQuery.java @@ -0,0 +1,107 @@ +package ru.mipt.diht.students.annnvl.CQL; + +import java.time.LocalDate; +import java.time.LocalDateTime; +import java.time.temporal.ChronoUnit; + +import static ru.mipt.diht.students.annnvl.CQL.Aggregates.avg; +import static ru.mipt.diht.students.annnvl.CQL.Aggregates.count; +import static ru.mipt.diht.students.annnvl.CQL.CollectionQuery.Student.student; +import static ru.mipt.diht.students.annnvl.CQL.Conditions.rlike; +import static ru.mipt.diht.students.annnvl.CQL.OrderByConditions.asc; +import static ru.mipt.diht.students.annnvl.CQL.OrderByConditions.desc; +import static ru.mipt.diht.students.annnvl.CQL.Sources.list; +import static ru.mipt.diht.students.annnvl.CQL.impl.FromStmt.from; + +public class CollectionQuery { + + public static void main(String[] args) { + Iterable statistics = + from(list( + student("ivanov", LocalDate.parse("1986-08-06"), "494"), + student("ivanov", LocalDate.parse("1986-08-06"), "494"))) + .select(Statistics.class, Student::getGroup, count(Student::getGroup), avg(Student::age)) + .where(rlike(Student::getName, ".*ov").and(s -> s.age() > 20)) + .groupBy(Student::getGroup) + .having(s -> s.getCount() > 0) + .orderBy(asc(Student::getGroup), desc(count(Student::getGroup))) + .limit(100) + .union() + .from(list(student("ivanov", LocalDate.parse("1985-08-06"), "494"))) + .selectDistinct(Statistics.class, s -> "all", count(s -> 1), avg(Student::age)) + .execute(); + System.out.println(statistics); + } + + + public static class Student { + private final String name; + + private final LocalDate dateOfBith; + + private final String group; + + public String getName() { + return name; + } + + public Student(String name, LocalDate dateOfBith, String group) { + this.name = name; + this.dateOfBith = dateOfBith; + this.group = group; + } + + public LocalDate getDateOfBith() { + return dateOfBith; + } + + public String getGroup() { + return group; + } + + public long age() { + return ChronoUnit.YEARS.between(getDateOfBith(), LocalDateTime.now()); + } + + public static Student student(String name, LocalDate dateOfBith, String group) { + return new Student(name, dateOfBith, group); + } + } + + + public static class Statistics { + + private final String group; + private final Long count; + private final Long age; + + public String getGroup() { + return group; + } + + public Long getCount() { + return count; + } + + + public Long getAge() { + return age; + } + + public Statistics(String group, Long count, Long age) { + this.group = group; + this.count = count; + this.age = age; + } + + @Override + public String toString() { + return "Statistics{" + + "group='" + group + '\'' + + ", count=" + count + + ", age=" + age + + '}'; + } + } + +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Conditions.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Conditions.java new file mode 100644 index 0000000..5ed9e17 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Conditions.java @@ -0,0 +1,37 @@ +package ru.mipt.diht.students.annnvl.CQL; + +import java.util.function.Function; +import java.util.function.Predicate; + +/** + * Where clause conditions. + */ +public class Conditions { + + /** + * Matches string result of expression against regexp pattern. + * + * @param expression expression result to match + * @param regexp pattern to match to + * @param source object type + * @return + */ + public static Predicate rlike(Function expression, String regexp) { + return element -> expression.apply(element).matches(regexp); + } + + /** + * Matches string result of expression against SQL like pattern. + * + * @param expression expression result to match + * @param pattern pattern to match to + * @param source object type + * @return + */ + public static Predicate like(Function expression, String pattern) { + String newpattern = pattern.toLowerCase(); + newpattern = newpattern.replace(".", "\\.").replace("?", ".").replace("%", ".*"); + return rlike(expression, newpattern); + } + +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/OrderByConditions.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/OrderByConditions.java new file mode 100644 index 0000000..a9772d4 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/OrderByConditions.java @@ -0,0 +1,37 @@ +package ru.mipt.diht.students.annnvl.CQL; + +import java.util.Comparator; +import java.util.function.Function; + +/** + * OrderBy sort order helper methods. + */ +public class OrderByConditions { + + /** + * Ascending comparator. + * + * @param expression + * @param + * @param + * @return + */ + public static > Comparator asc(Function expression) { + return (o1, o2) -> expression.apply(o1).compareTo(expression.apply(o2)); + } + + /** + * Descending comparator. + * + * @param expression + * @param + * @param + * @return + */ + public static > Comparator desc(Function expression) { + return (o1, o2) -> expression.apply(o2).compareTo(expression.apply(o1)); + } + +} + + diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Sources.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Sources.java new file mode 100644 index 0000000..99ca271 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/Sources.java @@ -0,0 +1,54 @@ +package ru.mipt.diht.students.annnvl.CQL; + +import java.io.InputStream; +import java.nio.file.Path; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Stream; + +/** + * Helper methods to create collections. + */ +public class Sources { + + /** + * @param items + * @param + * @return + */ + @SafeVarargs + public static List list(T... items) { + return Arrays.asList(items); + } + + /** + * @param items + * @param + * @return + */ + @SafeVarargs + public static Set set(T... items) { + throw new UnsupportedOperationException(); + } + + /** + * @param inputStream + * @param + * @return + */ + public static Stream lines(InputStream inputStream) { + throw new UnsupportedOperationException(); + } + + /** + * @param file + * @param + * @return + */ + public static Stream lines(Path file) { + throw new UnsupportedOperationException(); + } + +} + diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Aggregator.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Aggregator.java new file mode 100644 index 0000000..11ba369 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Aggregator.java @@ -0,0 +1,8 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.List; +import java.util.function.Function; + +public interface Aggregator extends Function { + R apply(List elements); +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Avg.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Avg.java new file mode 100644 index 0000000..dc79538 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Avg.java @@ -0,0 +1,27 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.List; +import java.util.function.Function; + +public class Avg implements Aggregator { + + private Function function; + public Avg(Function expression) { + this.function = expression; + } + + @Override + public Double apply(List elements) { + return elements + .stream() + .map(function) + .mapToDouble(element -> (Double) element) + .average() + .getAsDouble(); + } + + @Override + public Double apply(T t) { + return null; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Count.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Count.java new file mode 100644 index 0000000..8553f70 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Count.java @@ -0,0 +1,26 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.List; +import java.util.function.Function; + +public class Count implements Aggregator { + + private Function function; + public Count(Function expression) { + this.function = expression; + } + + @Override + public Integer apply(List elements) { + Long longAns = elements + .stream() + .map(function) + .distinct() + .count(); + return longAns.intValue(); + } + @Override + public Integer apply(T t) { + return null; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/FromStmt.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/FromStmt.java new file mode 100644 index 0000000..308073e --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/FromStmt.java @@ -0,0 +1,91 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; + +public class FromStmt { + + private List elements = new ArrayList(); + + public FromStmt(Iterable iterable) { + for (T element : iterable) { + elements.add(element); + } + } + + public static FromStmt from(Iterable iterable) { + return new FromStmt<>(iterable); + } + + @SafeVarargs + public final SelectStmt select(Class returnClass, Function... functions) { + return new SelectStmt<>(elements, returnClass, false, functions); + } + + @SafeVarargs + public final SelectStmt selectDistinct(Class returnClass, Function... functions) { + return new SelectStmt<>(elements, returnClass, true, functions); + } + + public final SelectStmt> select(Function first, Function second) { + return new SelectStmt<>(elements, false, first, second); + } + + public JoinClause join(Iterable iterable) { + return new JoinClause(elements, iterable); + } + + public class JoinClause { + + + private List firstElements = new ArrayList<>(); + private List secondElements = new ArrayList<>(); + private List> elements = new ArrayList<>(); + + public JoinClause(List firstElements, Iterable secondElements) { + this.firstElements.addAll(firstElements); + secondElements.forEach(this.secondElements::add); + } + + public FromStmt> on(BiPredicate condition) { + for (S first : firstElements) { + for (J second : secondElements) { + if (condition.test(first, second)) { + elements.add(new Tuple<>(first, second)); + } + } + } + return new FromStmt<>(elements); + } + + public > FromStmt> on( + Function leftKey, + Function rightKey) { + HashMap> map = new HashMap<>(); + for (J element : secondElements) { + K key = rightKey.apply(element); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(element); + } + for (S first : firstElements) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> elements.add(new Tuple<>(first, s))); + } + } + return new FromStmt<>(elements); + } + } + + public List getElements() { + return elements; + } +} + + diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Max.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Max.java new file mode 100644 index 0000000..4133fae --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Max.java @@ -0,0 +1,37 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.List; +import java.util.function.Function; + +public class Max> implements Aggregator { + + private Function function; + public Max(Function expression) { + this.function = expression; + } + + @Override + public R apply(List elements) { + return elements + .stream() + .map(function) + .reduce(null, (a, b) -> { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + if (a.compareTo(b) > 0) { + return a; + } else { + return b; + } + }); + } + + @Override + public R apply(T t) { + return null; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java new file mode 100644 index 0000000..e6b2ed4 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java @@ -0,0 +1,41 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.List; +import java.util.function.Function; + +public class Min> implements Aggregator { + + private Function function; + public Min(Function expression) { + this.function = expression; + } + + @Override + public R apply(List elements) { + return elements + .stream() + .map(function) +/* + .min(R::compareTo) + .get(); +*/ + .reduce(null, (a, b) -> { + if (a == null) { + return b; + } + if (b == null) { + return a; + } + if (a.compareTo(b) < 0) { + return a; + } else { + return b; + } + }); + } + + @Override + public R apply(T t) { + return null; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Query.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Query.java new file mode 100644 index 0000000..3b94998 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Query.java @@ -0,0 +1,13 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.stream.Stream; + +public interface Query { + + Iterable execute() throws NoSuchMethodException, IllegalAccessException, + InvocationTargetException, InstantiationException; + + Stream stream(); +} + diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/SelectStmt.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/SelectStmt.java new file mode 100644 index 0000000..54c57de --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/SelectStmt.java @@ -0,0 +1,230 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.lang.reflect.InvocationTargetException; +import java.util.*; +import java.util.function.Function; +import java.util.function.Predicate; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +public class SelectStmt { + + private boolean isDistinct; + private Class returnClass; + private Function[] functions; + private List elements; + + private List pastElements; + + private Predicate whereCondition; + private Comparator[] comparators; + private Predicate havingCondition; + private int numberOfObjects; + private Function[] groupByConditions; + + private CQLComparator cqlComparator; + private boolean isUnion; + private boolean isJoin; + + @SafeVarargs + public SelectStmt(List elements, Class returnClass, boolean isDistinct, Function... functions) { + this.elements = new ArrayList<>(); + this.elements.addAll(elements); + this.returnClass = returnClass; + this.isDistinct = isDistinct; + this.functions = functions; + this.numberOfObjects = -1; + this.isUnion = false; + this.isJoin = false; + } + + public SelectStmt(List elements, boolean isDistinct, Function first, Function second) { + this.elements = new ArrayList<>(); + this.elements.addAll(elements); + this.returnClass = elements.get(0).getClass(); + this.isDistinct = isDistinct; + this.functions = new Function[]{first, second}; + this.numberOfObjects = -1; + this.isUnion = false; + this.isJoin = true; + } + + @SafeVarargs + public SelectStmt(List pastElements, List elements, Class returnClass, + boolean isDistinct, Function... functions) { + this.elements = new ArrayList<>(); + this.elements.addAll(elements); + this.returnClass = returnClass; + this.isDistinct = isDistinct; + this.functions = functions; + this.numberOfObjects = -1; + this.isUnion = true; + this.pastElements = pastElements; + } + + public SelectStmt(List pastElements, List elements, boolean isDistinct, Function first, + Function second) { + this.elements = new ArrayList<>(); + this.elements.addAll(elements); + this.returnClass = elements.get(0).getClass(); + this.isDistinct = isDistinct; + this.functions = new Function[]{first, second}; + this.numberOfObjects = -1; + this.isUnion = true; + this.isJoin = true; + this.pastElements = pastElements; + } + + public SelectStmt where(Predicate predicate) { + this.whereCondition = predicate; + return this; + } + + @SafeVarargs + public final SelectStmt groupBy(Function... expressions) { + groupByConditions = expressions; + //groupByConditions = Arrays.asList(expressions); + return this; + } + + @SafeVarargs + public final SelectStmt orderBy(Comparator... comparators) { + this.comparators = comparators; + this.cqlComparator = new CQLComparator(comparators); + return this; + } + + public SelectStmt having(Predicate condition) { + this.havingCondition = condition; + return this; + } + + public SelectStmt limit(int amount) { + this.numberOfObjects = amount; + return this; + } + + public Iterable execute() throws NoSuchMethodException, IllegalAccessException, + InvocationTargetException, InstantiationException { + List result = new ArrayList<>(); + Class[] returnClasses = new Class[functions.length]; + if (whereCondition != null) { + elements = elements + .stream() + .filter(whereCondition::test) + .collect(Collectors.toList()); + } + if (groupByConditions != null) { + + Map> groupedMap = elements + .stream() + .collect(Collectors.groupingBy((T element) -> { + List answer = new ArrayList<>(); + for (int i = 0; i < groupByConditions.length; ++i) { + answer.add(groupByConditions[i].apply(element)); + } +/* + List answer = groupByConditions + .stream() + .map(cond -> cond.apply(element)) + .collect(Collectors.toList()); +*/ + return answer.hashCode(); + })); + + List> groupedList = groupedMap + .entrySet() + .stream() + .map(Map.Entry::getValue) + .collect(Collectors.toList()); + + Object[] arguments = new Object[functions.length]; + for (List group : groupedList) { + for (int i = 0; i < functions.length; i++) { + if (functions[i] instanceof Aggregator) { + arguments[i] = ((Aggregator) functions[i]).apply(group); + } else { + arguments[i] = functions[i].apply(group.get(0)); + } + returnClasses[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) returnClass.getConstructor(returnClasses).newInstance(arguments); + result.add(newElement); + } + } + } else { + Object[] arguments = new Object[functions.length]; + for (T element : this.elements) { + for (int i = 0; i < functions.length; i++) { + arguments[i] = functions[i].apply(element); + if (functions[i] instanceof Aggregator) { + List currArg = new ArrayList<>(); + currArg.add(element); + arguments[i] = ((Aggregator) functions[i]).apply(currArg); + } else { + arguments[i] = functions[i].apply(element); + } + returnClasses[i] = arguments[i].getClass(); + } + if (isJoin) { + Tuple newElement = new Tuple(arguments[0], arguments[1]); + result.add((R) newElement); + } else { + R newElement = (R) returnClass.getConstructor(returnClasses).newInstance(arguments); + result.add(newElement); + } + } + } + Stream resultStream = result.stream(); + if (havingCondition != null) { + resultStream = resultStream.filter(havingCondition::test); + } + if (isDistinct) { + resultStream = resultStream.distinct(); + } + if (comparators != null) { + resultStream = resultStream.sorted(cqlComparator); + } + if (numberOfObjects != -1) { + resultStream = resultStream.limit(numberOfObjects); + } + result = resultStream.collect(Collectors.toList()); + if (isUnion) { + pastElements.addAll(result); + result = pastElements; + } + return result; + } + + public UnionStmt union() throws InvocationTargetException, NoSuchMethodException, + InstantiationException, IllegalAccessException { + List result = (List) this.execute(); + if (isJoin) { + return new UnionStmt<>(result, true); + } else { + return new UnionStmt<>(result); + } + } + + public class CQLComparator implements Comparator { + private Comparator[] comparators; + @SafeVarargs + public CQLComparator(Comparator... comparators) { + this.comparators = comparators; + } + + @Override + public int compare(K first, K second) { + for (Comparator comparator : comparators) { + if (comparator.compare(first, second) != 0) { + return comparator.compare(first, second); + } + } + return 0; + } + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Tuple.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Tuple.java new file mode 100644 index 0000000..cefbaad --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Tuple.java @@ -0,0 +1,28 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +public class Tuple { + + private final F first; + private final S second; + + public Tuple(F first, S second) { + this.first = first; + this.second = second; + } + + public F getFirst() { + return first; + } + + public S getSecond() { + return second; + } + + @Override + public String toString() { + return "Tuple{" + + "first=" + first + + ", second=" + second + + '}'; + } +} \ No newline at end of file diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/UnionStmt.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/UnionStmt.java new file mode 100644 index 0000000..64c2497 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/UnionStmt.java @@ -0,0 +1,119 @@ +package ru.mipt.diht.students.annnvl.CQL.impl; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.function.BiPredicate; +import java.util.function.Function; +import java.util.stream.Collectors; + +public class UnionStmt { + + private List pastElements = new ArrayList<>(); + + private List elements = new ArrayList<>(); + + private boolean isTuple; + + public UnionStmt(Iterable iterable) { + for (R curr : iterable) { + pastElements.add(curr); + } + this.isTuple = false; + } + + public UnionStmt(Iterable iterable, boolean isTuple) { + for (R curr : iterable) { + pastElements.add(curr); + } + this.isTuple = true; + } + + public FromClause from(Iterable elements) { + if (isTuple) { + return new FromClause(pastElements, elements); + } else { + return new FromClause(pastElements, /*(Iterable)*/ elements); + } + } + + public class FromClause { + private List pastElements = new ArrayList<>(); + + private List elements = new ArrayList<>(); + + public FromClause(Iterable pastElements, Iterable elements) { + for (R curr : pastElements) { + this.pastElements.add(curr); + } + for (S curr : elements) { + this.elements.add(curr); + } + } + @SafeVarargs + public final SelectStmt select(Class returnClass, Function... functions) { + return new SelectStmt((List) pastElements, elements, returnClass, false, functions); + } + + public final SelectStmt> select(Function first, Function second) { + return new SelectStmt>((List>) pastElements, elements, false, first, second); + } + + @SafeVarargs + public final SelectStmt selectDistinct(Class returnClass, Function... functions) { + return new SelectStmt((List) pastElements, elements, returnClass, true, functions); + } + + public JoinClause join(Iterable iterable) { + return new JoinClause(pastElements, elements, iterable); + } + } + + public class JoinClause { + + private List firstElements = new ArrayList<>(); + private List secondElements = new ArrayList<>(); + private List pastElements = new ArrayList<>(); + private List> elements = new ArrayList<>(); + + public JoinClause(List pastElements, List firstElements, Iterable secondElements) { + this.pastElements.addAll(pastElements.stream().collect(Collectors.toList())); + this.firstElements.addAll(firstElements.stream().collect(Collectors.toList())); + for (J curr : secondElements) { + this.secondElements.add(curr); + } + } + + public FromClause, R> on(BiPredicate condition) { + for (F first : firstElements) { + for (J second : secondElements) { + if (condition.test(first, second)) { + elements.add(new Tuple<>(first, second)); + } + } + } + return new FromClause<>(pastElements, elements); + } + + public > FromClause, R> on( + Function leftKey, + Function rightKey) { + HashMap> map = new HashMap<>(); + for (J element : secondElements) { + K key = rightKey.apply(element); + if (!map.containsKey(key)) { + map.put(key, new ArrayList<>()); + } + map.get(key).add(element); + } + for (F first : firstElements) { + K key = leftKey.apply(first); + if (map.containsKey(key)) { + List second = map.get(key); + second.forEach(s -> elements.add(new Tuple<>(first, s))); + } + } + return new FromClause<>(pastElements, elements); + } + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java index 9306bf4..b817e60 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java @@ -25,14 +25,15 @@ synchronized void offer(List e) { data.addAll(e); } - synchronized void offer(List e, long timeout) { + synchronized void offer(List e, long timeout) throws InterruptedException{ timeout += System.currentTimeMillis(); - while ((data.size() + e.size() > maxQueueSize) && (timeout - System.currentTimeMillis()) > 0) { - Thread.yield(); + while ((data.size() + e.size() > maxQueueSize) && (timeout -= System.currentTimeMillis()) > 0) { + wait(timeout); } if (timeout > 0) { data.addAll(e); } + notifyAll(); } synchronized List take(int n) { @@ -46,18 +47,20 @@ synchronized List take(int n) { return answer; } - synchronized List take(int n, long timeout) { + synchronized List take(int n, long timeout) throws InterruptedException{ timeout += System.currentTimeMillis(); - while ((data.size() < n) && (timeout - System.currentTimeMillis()) > 0) { - Thread.yield(); + while ((data.size() < n) && (timeout -= System.currentTimeMillis()) > 0) { + wait(timeout); } if (timeout > 0) { List answer = new ArrayList(); for (int i = 0; i < n; i++) { answer.add(data.remove()); } + notifyAll(); return answer; } + notifyAll(); return null; } } diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java index f74b91f..aec2b59 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/Counter/CountedThread.java @@ -19,7 +19,7 @@ public final void run() { while (myNumber != currentThread) { Thread.yield(); } - System.out.println("Thread-" + (myNumber + 1) + "\n"); + System.out.println("Thread-" + (myNumber + 1)); currentThread = (currentThread + 1) % numberOfThreads; } } diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java index 8ec4736..11ffca8 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCall.java @@ -12,7 +12,7 @@ public static void main(String[] args) { } while (true) { RollCallerThread.makeEverybodyOk(); - System.out.println("Are you ready?\n"); + System.out.println("Are you ready?"); RollCallerThread.nextRollCall(); while (!RollCallerThread.everybodyasked()) { Thread.yield(); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java index db2d7d9..a0fd3c3 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/RollCall/RollCallerThread.java @@ -55,10 +55,10 @@ public final void run() { } timesNum++; if (rand.nextDouble() < LOWERBOUND) { - System.out.println("No\n"); + System.out.println("No"); everybodyOk = false; } else { - System.out.println("Yes\n"); + System.out.println("Yes"); } asked++; } From 7e50290f4f0003acc910a2aded0ddb5dbf693cf1 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Sat, 19 Dec 2015 06:21:15 +0300 Subject: [PATCH 5/8] fixed --- .../main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java index e6b2ed4..6eb926f 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java @@ -15,10 +15,7 @@ public R apply(List elements) { return elements .stream() .map(function) -/* - .min(R::compareTo) - .get(); -*/ + .reduce(null, (a, b) -> { if (a == null) { return b; From e4b8b2f5f1a976e4d00ac27fd26a8b3d1d0b5163 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Sat, 19 Dec 2015 06:43:10 +0300 Subject: [PATCH 6/8] TwitterStream added --- .../diht/students/annnvl/CQL/impl/Min.java | 2 +- .../annnvl/TwitterStream/Application.java | 64 +++++++++++++++++ .../annnvl/TwitterStream/Formatter.java | 35 ++++++++++ .../annnvl/TwitterStream/Location.java | 69 +++++++++++++++++++ .../students/annnvl/TwitterStream/Parser.java | 45 ++++++++++++ .../students/annnvl/TwitterStream/Search.java | 59 ++++++++++++++++ .../annnvl/TwitterStream/StatusParser.java | 42 +++++++++++ .../students/annnvl/TwitterStream/Stream.java | 56 +++++++++++++++ .../annnvl/TwitterStream/TimeParser.java | 42 +++++++++++ 9 files changed, 413 insertions(+), 1 deletion(-) create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java index 6eb926f..a737cd6 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/CQL/impl/Min.java @@ -15,7 +15,7 @@ public R apply(List elements) { return elements .stream() .map(function) - + .reduce(null, (a, b) -> { if (a == null) { return b; diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java new file mode 100644 index 0000000..1b161d2 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java @@ -0,0 +1,64 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import twitter4j.*; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.JCommander; + +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.util.Date; +import java.util.List; + +import static java.lang.Thread.sleep; + +public class Application { + public static void main(String[] args) throws Exception{ + Parser parameters = new Parser(); + JCommander command = null; + try { + command = new JCommander(parameters, args); + } catch (Exception errargs){ + System.out.println(errargs.getMessage()); + } + + if(parameters.isHelp()){ + try { + command.usage(); + } catch (NullPointerException ex){ + System.out.println(ex.getMessage()); + } + System.exit(0); + } + + if (parameters.isStream()) { + try { + TwitterStream twitterStream; + twitterStream = new TwitterStreamFactory().getInstance(); + Stream stream = new Stream(twitterStream); + stream.streamPrint(parameters); + } catch (TwitterException e) { + System.out.println(e.getMessage()); + } catch (Exception e) { + System.out.println(e.getMessage()); + System.exit(-1); + } + } else { + try { + Twitter twitter = new TwitterFactory().getInstance(); + Search search = new Search(twitter); + search.searchResult(parameters).stream().forEach(System.out::println); + } catch (NullPointerException e) { + System.err.println(e.getMessage()); + } catch (Exception e) { + System.out.println(e.getMessage()); + System.exit(-1); + } + } + + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java new file mode 100644 index 0000000..d968048 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java @@ -0,0 +1,35 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +public class Formatter { + @SuppressWarnings("checkstyle:magicnumber") + private static String formatScheme(long n, String[] cases) { + n = n % 100; + if (11 <= n + && n <= 19) { + return cases[0]; + } + n = n % 10; + if (n == 1) { + return cases[1]; + } + if (2 <= n + && n <= 4) { + return cases[2]; + } + return cases[0]; + } + static final String[] RETWEETS_CASES = {"ретвитов", "ретвит", "ретвита"}; + public static String retweet(long n) { + return formatScheme(n, RETWEETS_CASES); } + static final String[] MINUTES_CASES = {"минут", "минуту", "минуты"}; + public static String minutes(long n) { + return formatScheme(n, MINUTES_CASES); } + static final String[] HOURS_CASES = {"часов", "час", "часа"}; + public static String hours(long n) { + return formatScheme(n, HOURS_CASES); + } + static final String[] DAYS_CASES = {"дней", "день", "дня"}; + public static String days(long n) { + return formatScheme(n, DAYS_CASES); + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java new file mode 100644 index 0000000..4dfacfb --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java @@ -0,0 +1,69 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import com.google.maps.GeoApiContext; +import com.google.maps.GeocodingApi; +import com.google.maps.model.Bounds; +import com.google.maps.model.LatLng; +import com.google.maps.model.GeocodingResult; + +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.util.Properties; + +public class Location { + private static final double RADIUS_OF_EARTH = 6371; + + private GeocodingResult[] result; + private double radius; + + Location(String place) throws Exception { + if (!place.equals("nearby")) { + String apiKey = getKeyFromProperties(); + GeoApiContext context = new GeoApiContext().setApiKey(apiKey); + result = GeocodingApi.geocode(context, place).await(); + radius = calculateRadius(); + } + } + + private String getKeyFromProperties() throws IOException { + Properties prop = new Properties(); + try (InputStream input = new FileInputStream("twitter4j.properties")) { + prop.load(input); + } catch (FileNotFoundException e) { + System.err.println("Can't find the file : " + e.getMessage()); + throw e; + } catch (IOException e) { + System.err.println("Can't read the file : " + e.getMessage()); + throw e; + } + return prop.getProperty("googleApiKey"); + } + + public LatLng getLocation() { + return result[0].geometry.location; + } + + public double getRadius() { + return radius; + } + + private double calculateRadius() { + double phi1 = Math.toRadians(result[0].geometry.bounds.northeast.lat); + double phi2 = Math.toRadians(result[0].geometry.bounds.southwest.lat); + double dPhi = phi1 - phi2; + double lambda1 = Math.toRadians(result[0].geometry.bounds.northeast.lng); + double lambda2 = Math.toRadians(result[0].geometry.bounds.southwest.lng); + double dLambda = lambda1 - lambda2; + + double a = Math.sin(dPhi / 2) * Math.sin(dPhi / 2) + Math.cos(phi1) * Math.cos(phi2) * Math.sin(dLambda / 2) * Math.sin(dLambda / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + double distance = RADIUS_OF_EARTH * c; + return distance / 2; + } + + public final Bounds getBounds() { + return result[0].geometry.bounds; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java new file mode 100644 index 0000000..6d96536 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java @@ -0,0 +1,45 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import com.beust.jcommander.Parameter; +import com.beust.jcommander.validators.PositiveInteger; + +public class Parser { + private static final int STANDART_LIMIT = 100; + @Parameter(names = {"-l", "--limit"}, + validateWith = PositiveInteger.class, + description = "Number of tweets to show(only for no streaming mode)") + private int limit = STANDART_LIMIT; + + @Parameter(names = {"-s", "--stream"}, description = "Stream mode") + private boolean stream = false; + @Parameter(names = {"--hideRetweets"}, description = "Ignore retweets") + private boolean hideRetweets = false; + + @Parameter(names = { "-h", "--help"}, description = "Help mode", help = true) + private boolean help = false; + + @Parameter(names = {"-p", "--place"}, description = "Location or 'nearby'") + private String place = ""; + + @Parameter(names = {"-q", "--query"}, description = "Query or keywords for stream", required = true) + private String query = ""; + + public final String getQuery() { + return query; + } + public final String getPlace() { + return place; + } + public final Integer getLimit() { + return limit; + } + public final boolean isStream() { + return stream; + } + public final boolean isHideRetwitts() { + return hideRetweets; + } + public final boolean isHelp() { + return help; + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java new file mode 100644 index 0000000..c06eade --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java @@ -0,0 +1,59 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; +import twitter4j.*; +import twitter4j.conf.ConfigurationBuilder; + +import static java.util.stream.Collectors.toList; +import java.util.ArrayList; +import java.util.List; + +public class Search { + private static final int RADIUS = 1; + private final Twitter twitter; + public Search(Twitter loctwitter) { + this.twitter = loctwitter; + } + public static Query setQuery(Parser param) throws Exception { + Query query = new Query(param.getQuery()); + if (!param.getPlace().equals("")) { + if (!param.getPlace().equals("nearby")) { + Location googleFindPlace; + googleFindPlace = new Location(param.getPlace()); + GeoLocation geoLocation; + //широта: + geoLocation = new GeoLocation(googleFindPlace.getLocation().lat, googleFindPlace.getLocation().lng); + query.setGeoCode(geoLocation, googleFindPlace.getRadius(), Query.KILOMETERS); + } + } + return query; + } + public final List searchResult(Parser param) throws Exception { + ConfigurationBuilder cb = new ConfigurationBuilder(); + cb.setDebugEnabled(false) + .setOAuthConsumerKey("3b3vKQPtk7PoHEOekUedoIQPC") + .setOAuthConsumerSecret("ADrGDZORevHvt3iF9Ot3xwfMeufol2lsG58XmAcqyCSsGkQZkR") + .setOAuthAccessToken("2783476952-M6Pe8LR4gLYeKKDzdwjVKLkcFwMP38qDE1vgvP2") + .setOAuthAccessTokenSecret("mfAU8iq63vU3omwqje8SXRQr0QCfonoK4eSjrpX61gKe8"); + Twitter twitter = new TwitterFactory(cb.build()).getInstance(); + Query query = setQuery(param); + QueryResult result; + int limit = param.getLimit(); + int statusCount = 0; + List tweets = new ArrayList(); + do { + result = twitter.search(query); + for (Status status : result.getTweets()) { + tweets.add(status); + statusCount++; + limit--; + if (limit == 0) { + break; + } + } + query = result.nextQuery(); + } while (query != null && limit > 0); + /*if (statusCount == 0) { + throw new NoTweetsException("Твиты по запросу не найдены"); + }*/ + return tweets.stream().map(new StatusParser(param)::printStatus).collect(toList()); + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java new file mode 100644 index 0000000..eab5fb4 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java @@ -0,0 +1,42 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import twitter4j.Status; + +public class StatusParser { + public static final String ANSI_RESET = "\u001B[0m"; + public static final String ANSI_BLUE = "\u001B[34m"; + private Parser param; + public StatusParser(Parser paramDef) { + param = paramDef; + } + public final String printStatus(Status status) { + long currentTimeToFormat = System.currentTimeMillis(); + long tweetTimeToFormat = status.getCreatedAt().getTime(); + StringBuilder stringStatus = new StringBuilder(); + if (!param.isHideRetwitts()) { + if (status.isRetweet()) { + stringStatus.append("["). + append(TimeParser.printTime(currentTimeToFormat, tweetTimeToFormat)).append("] ") + .append(ANSI_BLUE) + .append("@").append(status.getUser().getScreenName()) + .append(ANSI_RESET).append(": ретвитнул " + ANSI_BLUE) + .append("@") + .append(status.getRetweetedStatus().getUser().getScreenName()) + .append(ANSI_RESET).append(": ") + .append(status.getRetweetedStatus().getText()); + } + } else { + stringStatus.append("["). + append(TimeParser.printTime(currentTimeToFormat, tweetTimeToFormat)).append("] ") + .append(ANSI_BLUE) + .append("@").append(status.getUser().getScreenName()) + .append(ANSI_RESET).append(": ").append(status.getText()); + if (status.getRetweetCount() != 0) { + stringStatus.append("(").append(status.getRetweetCount()).append(" ") + .append(Formatter.retweet(status.getRetweetCount())) + .append(")"); + } + } + return stringStatus.toString(); + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java new file mode 100644 index 0000000..e4b8f20 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java @@ -0,0 +1,56 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import twitter4j.*; +import twitter4j.conf.ConfigurationBuilder; + +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; + +public class Stream { + public static final long PAUSE = 1000; + private static TwitterStream twitterStream; + public Stream(TwitterStream twitterStreamm) { + this.twitterStream = twitterStreamm; + } + public static FilterQuery setFilter(Parser param) throws Exception { + String[] track = new String[1]; + track[0] = param.getQuery(); + long[] followArray = new long[0]; + FilterQuery filter = new FilterQuery(0, followArray, track); + if (!param.getPlace().equals("")) { + Location geoLocation; + geoLocation = new Location(param.getPlace()); + double[][] bounds = {{geoLocation.getBounds().southwest.lng, + geoLocation.getBounds().southwest.lat}, //широта южная + {geoLocation.getBounds().northeast.lng, //долгота северная + geoLocation.getBounds().northeast.lat}}; + filter.locations(bounds); + } + return filter; + } + public static void streamPrint(Parser param) + throws Exception {ConfigurationBuilder cb = new ConfigurationBuilder();cb.setDebugEnabled(false) + .setOAuthConsumerKey("3b3vKQPtk7PoHEOekUedoIQPC") + .setOAuthConsumerSecret("ADrGDZORevHvt3iF9Ot3xwfMeufol2lsG58XmAcqyCSsGkQZkR") + .setOAuthAccessToken("2783476952-M6Pe8LR4gLYeKKDzdwjVKLkcFwMP38qDE1vgvP2") + .setOAuthAccessTokenSecret("mfAU8iq63vU3omwqje8SXRQr0QCfonoK4eSjrpX61gKe8");TwitterStream twitterStreamm;twitterStreamm = new TwitterStreamFactory(cb.build()).getInstance();StatusAdapter listener = new StatusAdapter() { + @Override + public void onStatus(Status status) { + try { + Thread.sleep(PAUSE); + } catch (InterruptedException e) { + System.out.print(e.getMessage()); + } + System.out.println(new StatusParser(param).printStatus(status)); + } + };twitterStreamm.addListener(listener);if (param.getQuery() == "" && param.getPlace() == "") { + twitterStreamm.sample(); + } else { + FilterQuery filter = setFilter(param); + twitterStreamm.filter(filter); + } + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java new file mode 100644 index 0000000..3cb4a43 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java @@ -0,0 +1,42 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import java.time.LocalDateTime;import java.time.ZoneId;import java.time.temporal.ChronoUnit;import java.util.Date; + +public class TimeParser { + public static String printTime(long currentTimeToFormat, long tweetTimeToFormat) { + Formatter timeFormatter = new Formatter(); + LocalDateTime currentTime = new Date(currentTimeToFormat).toInstant() + .atZone(ZoneId.systemDefault()).toLocalDateTime(); + LocalDateTime tweetTime = new Date(tweetTimeToFormat).toInstant() + .atZone(ZoneId.systemDefault()).toLocalDateTime(); + if (ChronoUnit.MINUTES.between(tweetTime, currentTime) < 2) { + return "только что"; + } else { + if (ChronoUnit.HOURS.between(tweetTime, currentTime) < 1) { + return (new StringBuilder(). + append(ChronoUnit.MINUTES.between(tweetTime, currentTime)). + append(" ").append(timeFormatter.minutes(ChronoUnit.MINUTES.between(tweetTime, currentTime))). + append(" назад").toString()); + } else { + if (ChronoUnit.DAYS.between(tweetTime, currentTime) < 1) { + return (new StringBuilder(). + append(ChronoUnit.HOURS.between(tweetTime, currentTime)). + append(" ").append(timeFormatter.hours(ChronoUnit.HOURS.between(tweetTime, currentTime))). + append(" назад").toString()); + } else { + LocalDateTime currentDayTime = currentTime.toLocalDate().atStartOfDay(); + LocalDateTime tweetDayTime = tweetTime.toLocalDate().atStartOfDay(); + if (ChronoUnit.DAYS.between(tweetDayTime, currentDayTime) == 1) { + return ("вчера"); + } else { + return (new StringBuilder(). + append(ChronoUnit.DAYS.between(tweetDayTime, currentDayTime)). + append(" ").append(timeFormatter. + days(ChronoUnit.DAYS.between(tweetDayTime, currentDayTime))). + append(" назад").toString()); + } + } + } + } + } +} From c8e9d06883068313fda8575fe8970a86277de629 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Sat, 19 Dec 2015 07:20:06 +0300 Subject: [PATCH 7/8] TwitterStream fixed --- .../mipt/diht/students/annnvl/TwitterStream/Search.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java index c06eade..6f11dfa 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java @@ -29,10 +29,10 @@ public static Query setQuery(Parser param) throws Exception { public final List searchResult(Parser param) throws Exception { ConfigurationBuilder cb = new ConfigurationBuilder(); cb.setDebugEnabled(false) - .setOAuthConsumerKey("3b3vKQPtk7PoHEOekUedoIQPC") - .setOAuthConsumerSecret("ADrGDZORevHvt3iF9Ot3xwfMeufol2lsG58XmAcqyCSsGkQZkR") - .setOAuthAccessToken("2783476952-M6Pe8LR4gLYeKKDzdwjVKLkcFwMP38qDE1vgvP2") - .setOAuthAccessTokenSecret("mfAU8iq63vU3omwqje8SXRQr0QCfonoK4eSjrpX61gKe8"); + .setOAuthConsumerKey("qUMuGf1CDg1n8RT1ZKyPxYVxb") + .setOAuthConsumerSecret("ROnW8zh225ncTrbW5ZmqBNoCir9ktjgXdyNWvzO1i8RPMAmkrf") + .setOAuthAccessToken("3782742196-MgaebvnRBwHYk1LhONdOAK14zOIyE9XBLvTdpFh") + .setOAuthAccessTokenSecret("4Tz6FYRCGkEJzZGqFC5eX1jljlNOdbhDjZnkYT41gV8Wg"); Twitter twitter = new TwitterFactory(cb.build()).getInstance(); Query query = setQuery(param); QueryResult result; From 61d98241eefb200aba8abbbee17768576d9dcc41 Mon Sep 17 00:00:00 2001 From: Anna Vlasova Date: Sat, 19 Dec 2015 14:28:18 +0300 Subject: [PATCH 8/8] fix --- projects/annnvl/pom.xml | 2 +- .../Threads/BlockingQueue/BlockingQueue.java | 8 +- .../annnvl/TwitterStream/Application.java | 64 -------- .../annnvl/TwitterStream/FindPlace.java | 51 ++++++ .../students/annnvl/TwitterStream/Format.java | 27 ++++ .../annnvl/TwitterStream/Formatter.java | 35 ----- .../annnvl/TwitterStream/Location.java | 69 --------- .../annnvl/TwitterStream/Parameters.java | 62 ++++++++ .../students/annnvl/TwitterStream/Parser.java | 45 ------ .../annnvl/TwitterStream/PrintTime.java | 43 ++++++ .../students/annnvl/TwitterStream/Search.java | 59 ------- .../annnvl/TwitterStream/StatusParser.java | 42 ----- .../students/annnvl/TwitterStream/Stream.java | 56 ------- .../annnvl/TwitterStream/TimeParser.java | 42 ----- .../annnvl/TwitterStream/TwitterStream.java | 145 ++++++++++++++++++ .../annnvl/TwitterStream/FindPlaceTest.java | 35 +++++ .../annnvl/TwitterStream/FormatTest.java | 50 ++++++ .../annnvl/TwitterStream/PrintTimeTest.java | 44 ++++++ .../TwitterStream/TwitterSearchTest.java | 82 ++++++++++ .../TwitterStream/TwitterStreamTest.java | 60 ++++++++ .../java/twitter4j/Twitter4jTestUtils.java | 25 +++ 21 files changed, 629 insertions(+), 417 deletions(-) delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlace.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Format.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parameters.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTime.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java delete mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java create mode 100644 projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStream.java create mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlaceTest.java create mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FormatTest.java create mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTimeTest.java create mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterSearchTest.java create mode 100644 projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStreamTest.java create mode 100644 projects/annnvl/src/test/java/twitter4j/Twitter4jTestUtils.java diff --git a/projects/annnvl/pom.xml b/projects/annnvl/pom.xml index 4588988..2ca0a92 100644 --- a/projects/annnvl/pom.xml +++ b/projects/annnvl/pom.xml @@ -19,7 +19,7 @@ junit junit - 3.8.1 + 4.8.2 test diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java index b817e60..f1aa545 100644 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/Threads/BlockingQueue/BlockingQueue.java @@ -27,8 +27,8 @@ synchronized void offer(List e) { synchronized void offer(List e, long timeout) throws InterruptedException{ timeout += System.currentTimeMillis(); - while ((data.size() + e.size() > maxQueueSize) && (timeout -= System.currentTimeMillis()) > 0) { - wait(timeout); + while ((data.size() + e.size() > maxQueueSize) && (timeout - System.currentTimeMillis()) > 0) { + wait(timeout - System.currentTimeMillis()); } if (timeout > 0) { data.addAll(e); @@ -49,8 +49,8 @@ synchronized List take(int n) { synchronized List take(int n, long timeout) throws InterruptedException{ timeout += System.currentTimeMillis(); - while ((data.size() < n) && (timeout -= System.currentTimeMillis()) > 0) { - wait(timeout); + while ((data.size() < n) && (timeout - System.currentTimeMillis()) > 0) { + wait(timeout - System.currentTimeMillis()); } if (timeout > 0) { List answer = new ArrayList(); diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java deleted file mode 100644 index 1b161d2..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Application.java +++ /dev/null @@ -1,64 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import twitter4j.*; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.JCommander; - -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.util.Date; -import java.util.List; - -import static java.lang.Thread.sleep; - -public class Application { - public static void main(String[] args) throws Exception{ - Parser parameters = new Parser(); - JCommander command = null; - try { - command = new JCommander(parameters, args); - } catch (Exception errargs){ - System.out.println(errargs.getMessage()); - } - - if(parameters.isHelp()){ - try { - command.usage(); - } catch (NullPointerException ex){ - System.out.println(ex.getMessage()); - } - System.exit(0); - } - - if (parameters.isStream()) { - try { - TwitterStream twitterStream; - twitterStream = new TwitterStreamFactory().getInstance(); - Stream stream = new Stream(twitterStream); - stream.streamPrint(parameters); - } catch (TwitterException e) { - System.out.println(e.getMessage()); - } catch (Exception e) { - System.out.println(e.getMessage()); - System.exit(-1); - } - } else { - try { - Twitter twitter = new TwitterFactory().getInstance(); - Search search = new Search(twitter); - search.searchResult(parameters).stream().forEach(System.out::println); - } catch (NullPointerException e) { - System.err.println(e.getMessage()); - } catch (Exception e) { - System.out.println(e.getMessage()); - System.exit(-1); - } - } - - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlace.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlace.java new file mode 100644 index 0000000..6285497 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlace.java @@ -0,0 +1,51 @@ +package ru.mipt.diht.students.annnvl.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; + +public class FindPlace { + private static final double R = 6371; + private GeocodingResult[] result; + private double radius; + + FindPlace(String place) { + GeoApiContext context = new GeoApiContext().setApiKey("AIzaSyCAhkvmjepUzQUh9pA7g0K4QoQY2ncBno8"); + try { + result = GeocodingApi.geocode(context, place).await(); + radius = calculateRadius(); + } catch (Exception e) { + System.out.println(e.getMessage()); + System.exit(-1); + } + } + + private double calculateRadius() { + double x1 = Math.toRadians(result[0].geometry.bounds.northeast.lat); + double x2 = Math.toRadians(result[0].geometry.bounds.southwest.lat); + double dx = x1 - x2; + double lambda1; + lambda1 = Math.toRadians(result[0].geometry.bounds.northeast.lng); + double lambda2; + lambda2 = Math.toRadians(result[0].geometry.bounds.southwest.lng); + double dLambda = lambda1 - lambda2; + + double a = Math.sin(dx / 2) * Math.sin(dx / 2) + Math.cos(x1) * Math.cos(x2) + * Math.sin(dLambda / 2) * Math.sin(dLambda / 2); + double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + double distance = R * c; + return distance / 2; + } + + public final LatLng getLocation() { + return result[0].geometry.location; + } + public final double getRadius() { + return radius; + } + public final Bounds getBounds() { + return result[0].geometry.bounds; + } +}; diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Format.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Format.java new file mode 100644 index 0000000..2144491 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Format.java @@ -0,0 +1,27 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +public class Format { + + public static final String[] MINUTES = {" минуту ", " минуты ", " минут "}; + public static final String[] HOURS = {" час ", " часа ", " часов "}; + public static final String[] DAYS = {" день ", " дня ", " дней "}; + public static final String[] RETWEETS = {" ретвит", " ретвита", " ретвитов"}; + + public static final short FIVE = 5; + public static final short TEN = 10; + public static final short ELEVEN = 11; + public static final long FIFTEEN = 15; + public static final long HUNDRED = 100; + + public static int strForm(long number) { + if (number % TEN == 1 && number % HUNDRED != ELEVEN) { + return 0; + } + if (number % TEN > 1 && number % TEN < FIVE && (number % HUNDRED < FIVE || number % HUNDRED > FIFTEEN)) { + return 1; + } + return 2; + } +} + + diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java deleted file mode 100644 index d968048..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Formatter.java +++ /dev/null @@ -1,35 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -public class Formatter { - @SuppressWarnings("checkstyle:magicnumber") - private static String formatScheme(long n, String[] cases) { - n = n % 100; - if (11 <= n - && n <= 19) { - return cases[0]; - } - n = n % 10; - if (n == 1) { - return cases[1]; - } - if (2 <= n - && n <= 4) { - return cases[2]; - } - return cases[0]; - } - static final String[] RETWEETS_CASES = {"ретвитов", "ретвит", "ретвита"}; - public static String retweet(long n) { - return formatScheme(n, RETWEETS_CASES); } - static final String[] MINUTES_CASES = {"минут", "минуту", "минуты"}; - public static String minutes(long n) { - return formatScheme(n, MINUTES_CASES); } - static final String[] HOURS_CASES = {"часов", "час", "часа"}; - public static String hours(long n) { - return formatScheme(n, HOURS_CASES); - } - static final String[] DAYS_CASES = {"дней", "день", "дня"}; - public static String days(long n) { - return formatScheme(n, DAYS_CASES); - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java deleted file mode 100644 index 4dfacfb..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Location.java +++ /dev/null @@ -1,69 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import com.google.maps.GeoApiContext; -import com.google.maps.GeocodingApi; -import com.google.maps.model.Bounds; -import com.google.maps.model.LatLng; -import com.google.maps.model.GeocodingResult; - -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.Properties; - -public class Location { - private static final double RADIUS_OF_EARTH = 6371; - - private GeocodingResult[] result; - private double radius; - - Location(String place) throws Exception { - if (!place.equals("nearby")) { - String apiKey = getKeyFromProperties(); - GeoApiContext context = new GeoApiContext().setApiKey(apiKey); - result = GeocodingApi.geocode(context, place).await(); - radius = calculateRadius(); - } - } - - private String getKeyFromProperties() throws IOException { - Properties prop = new Properties(); - try (InputStream input = new FileInputStream("twitter4j.properties")) { - prop.load(input); - } catch (FileNotFoundException e) { - System.err.println("Can't find the file : " + e.getMessage()); - throw e; - } catch (IOException e) { - System.err.println("Can't read the file : " + e.getMessage()); - throw e; - } - return prop.getProperty("googleApiKey"); - } - - public LatLng getLocation() { - return result[0].geometry.location; - } - - public double getRadius() { - return radius; - } - - private double calculateRadius() { - double phi1 = Math.toRadians(result[0].geometry.bounds.northeast.lat); - double phi2 = Math.toRadians(result[0].geometry.bounds.southwest.lat); - double dPhi = phi1 - phi2; - double lambda1 = Math.toRadians(result[0].geometry.bounds.northeast.lng); - double lambda2 = Math.toRadians(result[0].geometry.bounds.southwest.lng); - double dLambda = lambda1 - lambda2; - - double a = Math.sin(dPhi / 2) * Math.sin(dPhi / 2) + Math.cos(phi1) * Math.cos(phi2) * Math.sin(dLambda / 2) * Math.sin(dLambda / 2); - double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); - double distance = RADIUS_OF_EARTH * c; - return distance / 2; - } - - public final Bounds getBounds() { - return result[0].geometry.bounds; - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parameters.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parameters.java new file mode 100644 index 0000000..338b42a --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parameters.java @@ -0,0 +1,62 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import com.beust.jcommander.Parameter; + +class Parameters { + + public static final int HUNDRED = 100; + @Parameter(names = {"-q", "--query"}, + description = "Запрос или ключевые слова") + private String query = ""; + @Parameter(names = {"-p", "--place"}, + description = "Место поиска") + private String place = ""; + @Parameter(names = {"-s", "--stream"}, + description = "Стрим") + private boolean stream = false; + @Parameter(names = {"--hideRetwitts"}, + description = "Прятать ретвиты") + private boolean hideRetweets = false; + @Parameter(names = {"-h", "--help"}, + description = "Выводит подсказку") + private boolean help = false; + @Parameter(names = {"-l", "--limit"}, + description = "Ограничение на количество" + " выводимых твитов (не в стриме)") + private Integer limit = HUNDRED; + + public final String getQuery() { + return query; + } + + public final String getPlace() { + return place; + } + + public final Integer getLimit() { + return limit; + } + + public final boolean isStream() { + return stream; + } + + public final boolean isHideRetweets() { + return hideRetweets; + } + + public final boolean isHelp() { + return help; + } + + public final void setQuery(String query) { query = query; } + + public final void setLimit(Integer limit) { limit = limit; } + + public final void setStream(boolean stream) { stream = stream; } + + public final void setHideRetweets(boolean hideRetweets) { hideRetweets = hideRetweets; } + + public final void setHelp(boolean help) { help = help; } + + public final void setPlace(String place) { place = place; } +}; diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java deleted file mode 100644 index 6d96536..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Parser.java +++ /dev/null @@ -1,45 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import com.beust.jcommander.Parameter; -import com.beust.jcommander.validators.PositiveInteger; - -public class Parser { - private static final int STANDART_LIMIT = 100; - @Parameter(names = {"-l", "--limit"}, - validateWith = PositiveInteger.class, - description = "Number of tweets to show(only for no streaming mode)") - private int limit = STANDART_LIMIT; - - @Parameter(names = {"-s", "--stream"}, description = "Stream mode") - private boolean stream = false; - @Parameter(names = {"--hideRetweets"}, description = "Ignore retweets") - private boolean hideRetweets = false; - - @Parameter(names = { "-h", "--help"}, description = "Help mode", help = true) - private boolean help = false; - - @Parameter(names = {"-p", "--place"}, description = "Location or 'nearby'") - private String place = ""; - - @Parameter(names = {"-q", "--query"}, description = "Query or keywords for stream", required = true) - private String query = ""; - - public final String getQuery() { - return query; - } - public final String getPlace() { - return place; - } - public final Integer getLimit() { - return limit; - } - public final boolean isStream() { - return stream; - } - public final boolean isHideRetwitts() { - return hideRetweets; - } - public final boolean isHelp() { - return help; - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTime.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTime.java new file mode 100644 index 0000000..7ce73b7 --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTime.java @@ -0,0 +1,43 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import java.time.LocalDateTime; +import java.time.ZoneId; +import java.time.temporal.ChronoUnit; +import java.util.Date; + +public class PrintTime { + + public static String printTime(long tweetForm, long curForm) { + + Format timeFormat = new Format(); + + LocalDateTime curTime = new Date(curForm).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + LocalDateTime tweetTime = new Date(tweetForm).toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime(); + + if (ChronoUnit.MINUTES.between(tweetTime, curTime) < 2) { + return "только что"; + } else { + if (ChronoUnit.HOURS.between(tweetTime, curTime) < 1) { + return new StringBuilder().append(ChronoUnit.MINUTES.between(tweetTime, curTime)) + .append(timeFormat.MINUTES[timeFormat.strForm(ChronoUnit.MINUTES.between(tweetTime, curTime))]) + .append("назад").toString(); + } else { + if (ChronoUnit.DAYS.between(tweetTime, curTime) < 1) { + return new StringBuilder().append(ChronoUnit.HOURS.between(tweetTime, curTime)) + .append(timeFormat.HOURS[timeFormat.strForm(ChronoUnit.HOURS.between(tweetTime, curTime))]) + .append("назад").toString(); + } else { + LocalDateTime tweetDateTime = tweetTime.toLocalDate().atStartOfDay(); + LocalDateTime curDateTime = curTime.toLocalDate().atStartOfDay(); + if (ChronoUnit.DAYS.between(tweetDateTime, curDateTime) == 1) { + return "вчера"; + } else { + return new StringBuilder().append(ChronoUnit.DAYS.between(tweetDateTime, curDateTime)) + .append(timeFormat.DAYS[timeFormat.strForm(ChronoUnit.DAYS.between(tweetDateTime, curDateTime))]) + .append("назад").toString(); + } + } + } + } + } +} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java deleted file mode 100644 index 6f11dfa..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Search.java +++ /dev/null @@ -1,59 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; -import twitter4j.*; -import twitter4j.conf.ConfigurationBuilder; - -import static java.util.stream.Collectors.toList; -import java.util.ArrayList; -import java.util.List; - -public class Search { - private static final int RADIUS = 1; - private final Twitter twitter; - public Search(Twitter loctwitter) { - this.twitter = loctwitter; - } - public static Query setQuery(Parser param) throws Exception { - Query query = new Query(param.getQuery()); - if (!param.getPlace().equals("")) { - if (!param.getPlace().equals("nearby")) { - Location googleFindPlace; - googleFindPlace = new Location(param.getPlace()); - GeoLocation geoLocation; - //широта: - geoLocation = new GeoLocation(googleFindPlace.getLocation().lat, googleFindPlace.getLocation().lng); - query.setGeoCode(geoLocation, googleFindPlace.getRadius(), Query.KILOMETERS); - } - } - return query; - } - public final List searchResult(Parser param) throws Exception { - ConfigurationBuilder cb = new ConfigurationBuilder(); - cb.setDebugEnabled(false) - .setOAuthConsumerKey("qUMuGf1CDg1n8RT1ZKyPxYVxb") - .setOAuthConsumerSecret("ROnW8zh225ncTrbW5ZmqBNoCir9ktjgXdyNWvzO1i8RPMAmkrf") - .setOAuthAccessToken("3782742196-MgaebvnRBwHYk1LhONdOAK14zOIyE9XBLvTdpFh") - .setOAuthAccessTokenSecret("4Tz6FYRCGkEJzZGqFC5eX1jljlNOdbhDjZnkYT41gV8Wg"); - Twitter twitter = new TwitterFactory(cb.build()).getInstance(); - Query query = setQuery(param); - QueryResult result; - int limit = param.getLimit(); - int statusCount = 0; - List tweets = new ArrayList(); - do { - result = twitter.search(query); - for (Status status : result.getTweets()) { - tweets.add(status); - statusCount++; - limit--; - if (limit == 0) { - break; - } - } - query = result.nextQuery(); - } while (query != null && limit > 0); - /*if (statusCount == 0) { - throw new NoTweetsException("Твиты по запросу не найдены"); - }*/ - return tweets.stream().map(new StatusParser(param)::printStatus).collect(toList()); - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java deleted file mode 100644 index eab5fb4..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/StatusParser.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import twitter4j.Status; - -public class StatusParser { - public static final String ANSI_RESET = "\u001B[0m"; - public static final String ANSI_BLUE = "\u001B[34m"; - private Parser param; - public StatusParser(Parser paramDef) { - param = paramDef; - } - public final String printStatus(Status status) { - long currentTimeToFormat = System.currentTimeMillis(); - long tweetTimeToFormat = status.getCreatedAt().getTime(); - StringBuilder stringStatus = new StringBuilder(); - if (!param.isHideRetwitts()) { - if (status.isRetweet()) { - stringStatus.append("["). - append(TimeParser.printTime(currentTimeToFormat, tweetTimeToFormat)).append("] ") - .append(ANSI_BLUE) - .append("@").append(status.getUser().getScreenName()) - .append(ANSI_RESET).append(": ретвитнул " + ANSI_BLUE) - .append("@") - .append(status.getRetweetedStatus().getUser().getScreenName()) - .append(ANSI_RESET).append(": ") - .append(status.getRetweetedStatus().getText()); - } - } else { - stringStatus.append("["). - append(TimeParser.printTime(currentTimeToFormat, tweetTimeToFormat)).append("] ") - .append(ANSI_BLUE) - .append("@").append(status.getUser().getScreenName()) - .append(ANSI_RESET).append(": ").append(status.getText()); - if (status.getRetweetCount() != 0) { - stringStatus.append("(").append(status.getRetweetCount()).append(" ") - .append(Formatter.retweet(status.getRetweetCount())) - .append(")"); - } - } - return stringStatus.toString(); - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java deleted file mode 100644 index e4b8f20..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/Stream.java +++ /dev/null @@ -1,56 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import twitter4j.*; -import twitter4j.conf.ConfigurationBuilder; - -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; - -public class Stream { - public static final long PAUSE = 1000; - private static TwitterStream twitterStream; - public Stream(TwitterStream twitterStreamm) { - this.twitterStream = twitterStreamm; - } - public static FilterQuery setFilter(Parser param) throws Exception { - String[] track = new String[1]; - track[0] = param.getQuery(); - long[] followArray = new long[0]; - FilterQuery filter = new FilterQuery(0, followArray, track); - if (!param.getPlace().equals("")) { - Location geoLocation; - geoLocation = new Location(param.getPlace()); - double[][] bounds = {{geoLocation.getBounds().southwest.lng, - geoLocation.getBounds().southwest.lat}, //широта южная - {geoLocation.getBounds().northeast.lng, //долгота северная - geoLocation.getBounds().northeast.lat}}; - filter.locations(bounds); - } - return filter; - } - public static void streamPrint(Parser param) - throws Exception {ConfigurationBuilder cb = new ConfigurationBuilder();cb.setDebugEnabled(false) - .setOAuthConsumerKey("3b3vKQPtk7PoHEOekUedoIQPC") - .setOAuthConsumerSecret("ADrGDZORevHvt3iF9Ot3xwfMeufol2lsG58XmAcqyCSsGkQZkR") - .setOAuthAccessToken("2783476952-M6Pe8LR4gLYeKKDzdwjVKLkcFwMP38qDE1vgvP2") - .setOAuthAccessTokenSecret("mfAU8iq63vU3omwqje8SXRQr0QCfonoK4eSjrpX61gKe8");TwitterStream twitterStreamm;twitterStreamm = new TwitterStreamFactory(cb.build()).getInstance();StatusAdapter listener = new StatusAdapter() { - @Override - public void onStatus(Status status) { - try { - Thread.sleep(PAUSE); - } catch (InterruptedException e) { - System.out.print(e.getMessage()); - } - System.out.println(new StatusParser(param).printStatus(status)); - } - };twitterStreamm.addListener(listener);if (param.getQuery() == "" && param.getPlace() == "") { - twitterStreamm.sample(); - } else { - FilterQuery filter = setFilter(param); - twitterStreamm.filter(filter); - } - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java deleted file mode 100644 index 3cb4a43..0000000 --- a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TimeParser.java +++ /dev/null @@ -1,42 +0,0 @@ -package ru.mipt.diht.students.annnvl.TwitterStream; - -import java.time.LocalDateTime;import java.time.ZoneId;import java.time.temporal.ChronoUnit;import java.util.Date; - -public class TimeParser { - public static String printTime(long currentTimeToFormat, long tweetTimeToFormat) { - Formatter timeFormatter = new Formatter(); - LocalDateTime currentTime = new Date(currentTimeToFormat).toInstant() - .atZone(ZoneId.systemDefault()).toLocalDateTime(); - LocalDateTime tweetTime = new Date(tweetTimeToFormat).toInstant() - .atZone(ZoneId.systemDefault()).toLocalDateTime(); - if (ChronoUnit.MINUTES.between(tweetTime, currentTime) < 2) { - return "только что"; - } else { - if (ChronoUnit.HOURS.between(tweetTime, currentTime) < 1) { - return (new StringBuilder(). - append(ChronoUnit.MINUTES.between(tweetTime, currentTime)). - append(" ").append(timeFormatter.minutes(ChronoUnit.MINUTES.between(tweetTime, currentTime))). - append(" назад").toString()); - } else { - if (ChronoUnit.DAYS.between(tweetTime, currentTime) < 1) { - return (new StringBuilder(). - append(ChronoUnit.HOURS.between(tweetTime, currentTime)). - append(" ").append(timeFormatter.hours(ChronoUnit.HOURS.between(tweetTime, currentTime))). - append(" назад").toString()); - } else { - LocalDateTime currentDayTime = currentTime.toLocalDate().atStartOfDay(); - LocalDateTime tweetDayTime = tweetTime.toLocalDate().atStartOfDay(); - if (ChronoUnit.DAYS.between(tweetDayTime, currentDayTime) == 1) { - return ("вчера"); - } else { - return (new StringBuilder(). - append(ChronoUnit.DAYS.between(tweetDayTime, currentDayTime)). - append(" ").append(timeFormatter. - days(ChronoUnit.DAYS.between(tweetDayTime, currentDayTime))). - append(" назад").toString()); - } - } - } - } - } -} diff --git a/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStream.java b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStream.java new file mode 100644 index 0000000..d96639b --- /dev/null +++ b/projects/annnvl/src/main/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStream.java @@ -0,0 +1,145 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import twitter4j.*; +import com.beust.jcommander.JCommander; + +import java.util.ArrayList; +import java.util.List; + +import static java.lang.Thread.sleep; + +public class TwitterStream { + + public static final int PAUSE = 1000; + + public static void printTime(Status status) { + PrintTime printer = new PrintTime(); + System.out.print(new StringBuilder().append("[") + .append(printer.printTime(status.getCreatedAt().getTime(), System.currentTimeMillis())).append("]")); + } + + public static void printTweet(Status status, boolean hideRetweets) { + if (status.isRetweet()) { + if (!hideRetweets) { + printTime(status); + System.out.println(new StringBuilder().append("@").append(status.getUser().getName()) + .append(" ретвитнул: @").append(status.getRetweetedStatus().getUser().getName()).append(": ") + .append(status.getRetweetedStatus().getText()).toString()); + } + } else { + Format retweetFormat = new Format(); + printTime(status); + System.out.print(new StringBuilder().append("@").append(status.getUser().getName()).append(": ") + .append(status.getText()).append(retweetFormat.strForm(status.getRetweetCount()))); + System.out.println(); + } + } + + public static Query setQuery(Parameters param) throws Exception { + Query query = new Query(param.getQuery()); + if (!param.getPlace().isEmpty()) { + FindPlace googleFindPlace; + googleFindPlace = new FindPlace(param.getPlace()); + GeoLocation geoLocation; + geoLocation = new GeoLocation(googleFindPlace.getLocation().lat, googleFindPlace.getLocation().lng); + query.setGeoCode(geoLocation, googleFindPlace.getRadius(), Query.KILOMETERS); + } + return query; + } + + public static List search(Parameters param) throws Exception { + Twitter twitter = new TwitterFactory().getInstance(); + Query query = setQuery(param); + QueryResult result; + int limit = param.getLimit(); + int statusCount = 0; + List tweets = new ArrayList<>(); + do { + result = twitter.search(query); + for (Status status : result.getTweets()) { + if (status.isRetweet() && param.isHideRetweets()) + continue; + tweets.add(status); + printTime(status); + printTweet(status, param.isHideRetweets()); + statusCount++; + limit--; + if (limit == 0) { + break; + } + } + query = result.nextQuery(); + } while (query != null && limit > 0); + if (statusCount == 0) { + System.out.println("Подходящих твитов нет"); + } + return tweets; + } + + public static FilterQuery setFilter(Parameters param) throws Exception{ + String[] track = new String[1]; + track[0] = param.getQuery(); + long[] follow = new long[0]; + FilterQuery filter = new FilterQuery(0, follow, track); + if (!param.getPlace().isEmpty()) { + FindPlace googleFindPlace; + googleFindPlace = new FindPlace(param.getPlace()); + double[][] bounds = {{googleFindPlace.getBounds().southwest.lng, googleFindPlace.getBounds().southwest.lat}, + {googleFindPlace.getBounds().northeast.lng, googleFindPlace.getBounds().northeast.lat}}; + filter.locations(bounds); + } + return filter; + } + + public static void stream(Parameters param, StatusListener listener) throws Exception { + twitter4j.TwitterStream twitterStream; + twitterStream = new TwitterStreamFactory().getInstance(); + twitterStream.addListener(listener); + if (param.getQuery() == "" && param.getPlace() == "") { + twitterStream.sample(); + } else { + FilterQuery filter = setFilter(param); + twitterStream.filter(filter); + } + } + + public static void main(String[] args) throws Exception { + final Parameters param = new Parameters(); + JCommander cmd = new JCommander(param, args); + if (param.isHelp()) { + cmd.usage(); + System.exit(0); + } + if (param.isStream()) { + StatusListener listener = new StatusAdapter() { + @Override + public void onStatus(Status status) { + printTweet(status, param.isHideRetweets()); + try { + sleep(PAUSE); + } catch (InterruptedException e) { + System.out.println(e.getMessage()); + } + } + }; + try { + stream(param, listener); + } catch (TwitterException e) { + System.out.println(e.getMessage()); + stream(param, listener); + } catch (Exception e) { + e.printStackTrace(); + } + } else { + try { + search(param); + } catch (TwitterException e) { + System.out.println(e.getMessage()); + search(param); + } catch (Exception e) { + e.printStackTrace(); + } + } + } +}; + diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlaceTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlaceTest.java new file mode 100644 index 0000000..246eea4 --- /dev/null +++ b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FindPlaceTest.java @@ -0,0 +1,35 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + + +import org.junit.Test; +import org.junit.runner.RunWith; +import junit.framework.TestCase; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class FindPlaceTest extends TestCase { + + static final double LAT_Moscow = 55.755826; + static final double LONG_Moscow = 37.6173; + + static final double LAT_London = 51.5085300; + static final double LONG_London = -0.1257400; + + static final double LAT_NewYork = 40.7142700; + static final double LONG_NewYork = -74.0059700; + + @Test + public void LocationTest() throws Exception { + FindPlace location1 = new FindPlace("Moscow"); + assert (LAT_Moscow == Math.rint(location1.getLocation().lat * 1000000.0) / 1000000.0); + assert (LONG_Moscow == Math.rint(location1.getLocation().lng * 1000000.0) / 1000000.0); + + FindPlace location2= new FindPlace("London"); + assert (LAT_London == Math.rint(location2.getLocation().lat * 1000000.0) / 1000000.0); + assert (LONG_London == Math.rint(location2.getLocation().lng * 1000000.0) / 1000000.0); + + FindPlace location3= new FindPlace("NewYork"); + assert (LAT_NewYork == Math.rint(location3.getLocation().lat * 1000000.0) / 1000000.0); + assert (LONG_NewYork == Math.rint(location3.getLocation().lng * 1000000.0) / 1000000.0); + } +} diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FormatTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FormatTest.java new file mode 100644 index 0000000..c6e0840 --- /dev/null +++ b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/FormatTest.java @@ -0,0 +1,50 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import org.junit.Assert; +import org.junit.Test; + +public class FormatTest { + @Test + public void testFormat() throws Exception { + Assert.assertEquals("минут", Format.MINUTES[Format.strForm(0)]); + Assert.assertEquals("минуту", Format.MINUTES[Format.strForm(1)]); + Assert.assertEquals("минуты", Format.MINUTES[Format.strForm(2)]); + Assert.assertEquals("минут", Format.MINUTES[Format.strForm(10)]); + Assert.assertEquals("минуты", Format.MINUTES[Format.strForm(32)]); + Assert.assertEquals("минут", Format.MINUTES[Format.strForm(55)]); + Assert.assertEquals("минуту", Format.MINUTES[Format.strForm(121)]); + Assert.assertEquals("минут", Format.MINUTES[Format.strForm(500)]); + Assert.assertEquals("минуты", Format.MINUTES[Format.strForm(672)]); + Assert.assertEquals("минут", Format.MINUTES[Format.strForm(765)]); + Assert.assertEquals("дней", Format.DAYS[Format.strForm(0)]); + Assert.assertEquals("день", Format.DAYS[Format.strForm(1)]); + Assert.assertEquals("дня", Format.DAYS[Format.strForm(2)]); + Assert.assertEquals("дня", Format.DAYS[Format.strForm(32)]); + Assert.assertEquals("дней", Format.DAYS[Format.strForm(55)]); + Assert.assertEquals("день", Format.DAYS[Format.strForm(121)]); + Assert.assertEquals("дней", Format.DAYS[Format.strForm(500)]); + Assert.assertEquals("дня", Format.DAYS[Format.strForm(672)]); + Assert.assertEquals("дней", Format.DAYS[Format.strForm(765)]); + Assert.assertEquals("часов", Format.HOURS[Format.strForm(0)]); + Assert.assertEquals("час", Format.HOURS[Format.strForm(1)]); + Assert.assertEquals("часа", Format.HOURS[Format.strForm(2)]); + Assert.assertEquals("часа", Format.HOURS[Format.strForm(3)]); + Assert.assertEquals("часов", Format.HOURS[Format.strForm(5)]); + Assert.assertEquals("часов", Format.HOURS[Format.strForm(7)]); + Assert.assertEquals("час", Format.HOURS[Format.strForm(21)]); + Assert.assertEquals("часа", Format.HOURS[Format.strForm(32)]); + Assert.assertEquals("часов", Format.HOURS[Format.strForm(55)]); + Assert.assertEquals("час", Format.HOURS[Format.strForm(121)]); + Assert.assertEquals("ретвитов", Format.RETWEETS[Format.strForm(0)]); + Assert.assertEquals("ретвит", Format.RETWEETS[Format.strForm(1)]); + Assert.assertEquals("ретвита", Format.RETWEETS[Format.strForm(2)]); + Assert.assertEquals("ретвита", Format.RETWEETS[Format.strForm(3)]); + Assert.assertEquals("ретвитов", Format.RETWEETS[Format.strForm(5)]); + Assert.assertEquals("ретвитов", Format.RETWEETS[Format.strForm(7)]); + Assert.assertEquals("ретвитов", Format.RETWEETS[Format.strForm(10)]); + Assert.assertEquals("ретвита", Format.RETWEETS[Format.strForm(32)]); + Assert.assertEquals("ретвитов",Format.RETWEETS[Format.strForm(55)]); + Assert.assertEquals("ретвит", Format.RETWEETS[Format.strForm(121)]); + Assert.assertEquals("ретвитов", Format.RETWEETS[Format.strForm(500)]); + } +} diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTimeTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTimeTest.java new file mode 100644 index 0000000..4357830 --- /dev/null +++ b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/PrintTimeTest.java @@ -0,0 +1,44 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.runners.MockitoJUnitRunner; + +import java.time.LocalDate; +import java.time.Month; +import java.time.ZoneId; + +import static org.hamcrest.Matchers.is; +import static org.junit.Assert.assertThat; + +@RunWith(MockitoJUnitRunner.class) +public class PrintTimeTest { + @Test + public void timePrinterTest() { + + assertThat(PrintTime.printTime(LocalDate.of(2009, Month.MARCH, 20).atTime(23, 59, 59) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), + LocalDate.of(2009, Month.DECEMBER, 21).atTime(0, 0, 0) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()), is("только что")); + + assertThat(PrintTime.printTime(LocalDate.of(2009, Month.MARCH, 19).atTime(0, 0, 1) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), + LocalDate.of(2009, Month.MARCH, 20).atTime(0, 0, 2) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()), is("вчера")); + + assertThat(PrintTime.printTime(LocalDate.of(2009, Month.MARCH, 20).atTime(0, 0, 1) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), + LocalDate.of(2009, Month.MARCH, 21).atTime(0, 0, 0) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()), is("23 часа назад")); + + assertThat(PrintTime.printTime(LocalDate.of(2009, Month.MARCH, 19).atTime(23, 59, 59) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), + LocalDate.of(2009, Month.MARCH, 21).atTime(0, 0, 0) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()), is("2 дня назад")); + + assertThat(PrintTime.printTime(LocalDate.of(2009, Month.MARCH, 19).atTime(23, 59, 59) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli(), + LocalDate.of(2009, Month.MARCH, 20).atTime(0, 2, 0) + .atZone(ZoneId.systemDefault()).toInstant().toEpochMilli()), is("2 минуты назад")); + } +} diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterSearchTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterSearchTest.java new file mode 100644 index 0000000..d3d3cd9 --- /dev/null +++ b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterSearchTest.java @@ -0,0 +1,82 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import org.junit.Before; +import org.junit.Test; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import twitter4j.Query; +import twitter4j.QueryResult; +import twitter4j.Status; +import twitter4j.Twitter; + +import java.util.ArrayList; +import java.util.List; + +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.hasProperty; +import static org.hamcrest.Matchers.hasSize; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; +import static org.mockito.Matchers.argThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; + +public class TwitterSearchTest { + @Mock + private Twitter twitter; + + @InjectMocks + private TwitterStream search; + public static List statuses; + + @Before + public void setUp() throws Exception { + QueryResult queryResult = mock(QueryResult.class); + when(queryResult.getTweets()).thenReturn(statuses); + when(queryResult.nextQuery()).thenReturn(null); + QueryResult emptyQueryResult = mock(QueryResult.class); + when(emptyQueryResult.getTweets()).thenReturn(new ArrayList()); + when(queryResult.nextQuery()).thenReturn(null); + } + + @Test + public void simpleSetQueryTest() throws Exception { + Parameters param = new Parameters(); + param.setQuery("cook"); + param.setStream(true); + param.setLimit(40); + param.setHideRetweets(true); + param.setHelp(false); + param.setPlace("Moscow"); + Query query = search.setQuery(param); + assertEquals(query.getQuery(), "cook"); + } + + @Test + public void limitSearchResultTest() throws Exception { + Parameters param = new Parameters(); + param.setQuery("cook"); + param.setStream(true); + param.setLimit(40); + param.setHideRetweets(false); + param.setHelp(false); + param.setPlace(""); + List tweets = search.search(param); + assertThat(tweets, hasSize(40)); + verify(twitter).search((Query) argThat(hasProperty("query", equalTo("cook")))); + } + + @Test + public void emptySearchResultTest() throws Exception { + Parameters param = new Parameters(); + param.setQuery("cook"); + param.setStream(true); + param.setLimit(40); + param.setHideRetweets(false); + param.setHelp(false); + param.setPlace(""); + List tweets = search.search(param); + assertThat(tweets, hasSize(0)); + } +} diff --git a/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStreamTest.java b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStreamTest.java new file mode 100644 index 0000000..70e6984 --- /dev/null +++ b/projects/annnvl/src/test/java/ru/mipt/diht/students/annnvl/TwitterStream/TwitterStreamTest.java @@ -0,0 +1,60 @@ +package ru.mipt.diht.students.annnvl.TwitterStream; + +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.runners.MockitoJUnitRunner; + +import twitter4j.*; +import static org.mockito.Mockito.verify; +import org.mockito.ArgumentCaptor; +import static org.junit.Assert.assertTrue; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.doAnswer; +import static org.mockito.Mockito.doNothing; + +import java.util.ArrayList; +import java.util.List; + +@RunWith(MockitoJUnitRunner.class) +public class TwitterStreamTest { + @Mock + twitter4j.TwitterStream twitterStream; + + @InjectMocks + TwitterStream stream; + public static List statuses; + + @BeforeClass + public static void loadSampleData() { + statuses = Twitter4jTestUtils.tweetsFromJson("/statuses.json"); + } + + @Test + public void streamResultTest() throws Exception { + ArgumentCaptor statusListener = ArgumentCaptor.forClass(StatusListener.class); + doNothing().when(twitterStream).addListener((StatusListener) statusListener.capture()); + doAnswer(i -> { + statuses.forEach(s -> statusListener.getValue().onStatus(s)); + return null; + }).when(twitterStream).filter(any(FilterQuery.class)); + List tweets = new ArrayList<>(); + + Parameters param = new Parameters(); + param.setQuery("mipt"); + param.setStream(true); + param.setLimit(100); + param.setHideRetweets(false); + param.setHelp(false); + param.setPlace(""); + + stream.stream(param, tweets::add); + assertTrue(tweets.size() == 13); + + verify(twitterStream).addListener((StatusListener) any(StatusAdapter.class)); + verify(twitterStream).filter(any(FilterQuery.class)); + } +} + diff --git a/projects/annnvl/src/test/java/twitter4j/Twitter4jTestUtils.java b/projects/annnvl/src/test/java/twitter4j/Twitter4jTestUtils.java new file mode 100644 index 0000000..1f789a7 --- /dev/null +++ b/projects/annnvl/src/test/java/twitter4j/Twitter4jTestUtils.java @@ -0,0 +1,25 @@ +package twitter4j; + +import org.apache.commons.io.IOUtils; +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.List; + +public class Twitter4jTestUtils { + public static List tweetsFromJson(String resource) { + try (InputStream inputStream = Twitter4jTestUtils.class.getResourceAsStream(resource)) { + JSONObject json = new JSONObject(IOUtils.toString(inputStream)); + JSONArray array = json.getJSONArray("statuses"); + List tweets = new ArrayList(array.length()); + for (int i = 0; i < array.length(); i++) { + JSONObject tweet = array.getJSONObject(i); + tweets.add(new StatusJSONImpl(tweet)); + } + return tweets; + } catch (IOException | JSONException | TwitterException e) { + throw new RuntimeException(e); + } + } +} +