diff --git a/Threads/pom.xml b/Threads/pom.xml new file mode 100644 index 0000000..cbc66f6 --- /dev/null +++ b/Threads/pom.xml @@ -0,0 +1,69 @@ + + + 4.0.0 + + Threads + Threads + 1.0-SNAPSHOT + jar + Threads + http://maven.apache.org + + + Threads + + + src/main/resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + + true + ru.fizteh.fivt.students.bulgakova.Threads.Mainclass + ru.fizteh.fivt.students.bulgakova.Threads + true + lib/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy-dependencies + package + + copy-dependencies + + + compile + ${project.build.directory}/lib + + + + + + + + + \ No newline at end of file diff --git a/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/BlockingQueue.java b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/BlockingQueue.java new file mode 100644 index 0000000..0b3b077 --- /dev/null +++ b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/BlockingQueue.java @@ -0,0 +1,52 @@ +package ru.fizteh.fivt.students.bulgakova.Threads; + +import javax.naming.LimitExceededException; +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.locks.ReentrantLock; + + +public class BlockingQueue { + + private int maxSize; + private Queue elements; + private ReentrantLock locker; + + + public BlockingQueue(int _size) { + maxSize = _size; + locker = new ReentrantLock(); + elements = new LinkedList(); + } + + void offer(List e) throws LimitExceededException { + if(e.size() + elements.size() <= maxSize) { + locker.lock(); + + for(E oneElem : e) { + elements.add(oneElem); + } + locker.unlock(); + } else { + throw new LimitExceededException(); + } + } + + List take(int n) throws LimitExceededException { + if(elements.size() >= n) { + locker.lock(); + + List returningList = new ArrayList(); + for(int i = 0; i < n; i++) { + returningList.add(elements.remove()); + } + + locker.unlock(); + return returningList; + } else { + throw new LimitExceededException(); + } + } +} \ No newline at end of file diff --git a/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Mainclass.java b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Mainclass.java new file mode 100644 index 0000000..26baf60 --- /dev/null +++ b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Mainclass.java @@ -0,0 +1,40 @@ +package ru.fizteh.fivt.students.bulgakova.Threads; + +import javax.naming.LimitExceededException; +import java.util.ArrayList; +import java.util.List; + + +public class Mainclass { + + public static void main(String args[]) throws InterruptedException { + + for (int i = 0; i < 3; i++) { + Rhymes rhymes = new Rhymes(5); + } + + + Muster muster = new Muster(5); + muster.Asking(); + + + BlockingQueue blockingQueue = new BlockingQueue(5); + List list1 = new ArrayList(); + list1.add(1); + list1.add(2); + list1.add(3); + list1.add(4); + list1.add(5); + + List myList2; + try { + blockingQueue.offer(list1); + myList2 = blockingQueue.take(2); + for(Integer i : myList2) { + System.out.print(i + " "); + } + } catch (LimitExceededException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Muster.java b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Muster.java new file mode 100644 index 0000000..eaeea38 --- /dev/null +++ b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Muster.java @@ -0,0 +1,76 @@ +package ru.fizteh.fivt.students.bulgakova.Threads; + +import java.util.ArrayList; +import java.util.Random; + + +public class Muster { + private boolean allThreadsAreReady; + private int threadsCount; + private ArrayList answers; + + public class AnsweringFlow extends Thread{ + private int index; + + public AnsweringFlow(int _index) { + index = _index; + } + + @Override + public void run() { + double random = new Random().nextDouble(); + if(random > 0.1) { + System.out.println("Yes"); + answers.set(index, Boolean.TRUE); + } else { + System.out.println("No"); + answers.set(index, Boolean.FALSE); + } + } + } + + public Muster(int _threadsCount) { + threadsCount = _threadsCount; + } + + public void Asking() throws InterruptedException{ + allThreadsAreReady = false; + + + answers = new ArrayList(); + for(int i = 0; i < threadsCount; i++) { + answers.add(false); + } + + + while (!allThreadsAreReady) { + ArrayList answeringThreads = new ArrayList(); + System.out.println("\nAre you ready?"); + + for(int i = 0; i < threadsCount; i++) { + answeringThreads.add(new AnsweringFlow(i)); + } + + for(AnsweringFlow answeringFlow: answeringThreads) { + answeringFlow.run(); + } + + for(AnsweringFlow answeringFlow: answeringThreads) { + try { + answeringFlow.join(); + } + catch(InterruptedException e) { + e.printStackTrace(); + } + } + + allThreadsAreReady = true; + for(Boolean answer : answers) { + if(!answer) { + allThreadsAreReady = false; + break; + } + } + } + } +} \ No newline at end of file diff --git a/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Rhymes.java b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Rhymes.java new file mode 100644 index 0000000..c0a9126 --- /dev/null +++ b/Threads/src/main/java/ru/fizteh/fivt/students/bulgakova/Threads/Rhymes.java @@ -0,0 +1,52 @@ +package ru.fizteh.fivt.students.bulgakova.Threads; + +import java.util.ArrayList; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import static java.lang.Thread.currentThread; + +public class Rhymes { + private static Object lock = new Object(); + private static BlockingQueue blockingQueue = new LinkedBlockingQueue(); + + public Rhymes(int threadsCount) throws InterruptedException{ + ArrayList threads = new ArrayList(threadsCount); + for (int i = 0; i < threadsCount; i++) { + threads.add(new Thread(new Flow(lock, blockingQueue), "Thread-" + i)); + (threads.get(i)).start(); + Thread.sleep(100); + } + + Thread.sleep(100); + + for (int i = 0; i < threadsCount; i++) { + synchronized (lock) { + lock.notify(); + } + System.out.println(" " + blockingQueue.take()); + threads.get(i).join(); + } + } + + public class Flow implements Runnable { + private Object lock; + private BlockingQueue blockingQueue; + + public Flow(Object _lock, BlockingQueue _blockingQueue) { + blockingQueue = _blockingQueue; + lock = _lock; + } + + public void run() { + synchronized (lock) { + try { + lock.wait(); + blockingQueue.put(currentThread().getName()); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } + +} diff --git a/TwitterModuleTests/pom.xml b/TwitterModuleTests/pom.xml new file mode 100644 index 0000000..ae4174d --- /dev/null +++ b/TwitterModuleTests/pom.xml @@ -0,0 +1,106 @@ + + + +4.0.0 +ru.fizteh.fivt.students.bulgakova.TwitterStream +TwitterS +jar +1.0-SNAPSHOT +TwitterFirst +http://maven.apache.org + + + junit + junit + 4.12 + + + + org.twitter4j + twitter4j-stream + 4.0.4 + + + + com.beust + jcommander + 1.48 + + + + org.mockito + mockito-core + 1.10.19 + test + + + + org.mockito + mockito-all + 1.9.5 + + + + org.hamcrest + hamcrest-all + 1.3 + + + + + + twitter + + + src/main/resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + + true + ru.fizteh.fivt.students.bulgakova.TwitterStream.TwitterMain + ru.fizteh.fivt.students.bulgakova.TwitterStream + true + lib/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy-dependencies + package + + copy-dependencies + + + compile + ${project.build.directory}/lib + + + + + + + diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java new file mode 100644 index 0000000..0c76efc --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java @@ -0,0 +1,85 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import twitter4j.*; + +import java.io.Writer; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +public class TwitterMain { + + private static Twitter twitter; + private static TwitterParser twitterParser; + private static TwitterOutput twitterOutput; + + private static Query query; + private static QueryResult queryResult; + private static BlockingQueue streamQueue; + + private static final int QUEUE_MAX_SIZE = 1000; + private static final int SLEEP_TIME = 1000; + + + public TwitterMain(TwitterParser _twitterParser) { + twitterParser = _twitterParser; + } + + private static StatusListener tweetListener = new StatusAdapter() { + public void onStatus(Status status) { + if (!twitterParser.getHideRetweets() || !status.isRetweet()) { + streamQueue.add(status); + } + } + }; + + private static void usualMode(Writer writer, int counter) throws Exception { + twitter = new TwitterFactory().getSingleton(); + query = new Query(twitterParser.getKeyword()); + queryResult = twitter.search(query); + Integer tweetsCounter = 0; + + while (tweetsCounter++ < twitterParser.getLimit()) { + for (twitter4j.Status status : queryResult.getTweets()) { + if (!twitterParser.getHideRetweets() || !status.isRetweet()) { + writer.write(twitterOutput.printTweet(status, true) + "\n"); + writer.flush(); + } + + if (tweetsCounter++ >= twitterParser.getLimit()) break; + + } + if (queryResult.hasNext()) { + queryResult = twitter.search(queryResult.nextQuery()); + } else { + break; + } + } + } + + private static void streamMode(Writer writer) throws Exception { + + TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + twitterStream.addListener(tweetListener); + streamQueue = new ArrayBlockingQueue(QUEUE_MAX_SIZE); + FilterQuery filterQuery = new FilterQuery(); + + filterQuery.track(new String[]{twitterParser.getKeyword()}); + twitterStream.filter(filterQuery); + + while(true) { + while (!streamQueue.isEmpty()) { + Status status = streamQueue.poll(); + writer.write(twitterOutput.printTweet(status, false) + "\n"); + writer.flush(); + Thread.sleep(SLEEP_TIME); + } + } + } + +} + + diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMainTest.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMainTest.java new file mode 100644 index 0000000..0d21753 --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMainTest.java @@ -0,0 +1,21 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +import org.junit.AfterClass; +import org.junit.BeforeClass; +import org.junit.Test; + +public class TwitterMainTest { + + @BeforeClass + public static void SetUpArguments() {} + + @AfterClass + public static void CleanUpArguments() {} + + @Test + public void WorkInStreamModeTest() {} + + @Test + public void WorkInCommonModeTest() {} + +} diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java new file mode 100644 index 0000000..05172ae --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java @@ -0,0 +1,111 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import twitter4j.Status; +import java.util.GregorianCalendar; +import java.util.Date; +import java.util.Calendar; + +public class TwitterOutput { + + public static TwitterOutput twitterOutput; + + private static String printedString; + + public static final Long SECOND = 1000L; + public static final Long MINUTE = SECOND * 60; + public static final Long TWO_MINUTES = MINUTE * 2; + public static final Long HOUR = MINUTE * 60; + public static final Long DAY = HOUR * 24; + + static boolean ifToday(GregorianCalendar date) { + GregorianCalendar today = new GregorianCalendar(); + + if ( (today.get(Calendar.DAY_OF_MONTH) == date.get(Calendar.DAY_OF_MONTH)) && (today.get(Calendar.MONTH) == date.get(Calendar.MONTH)) && (today.get(Calendar.YEAR) == date.get(Calendar.YEAR))) { + return true; + } else { + return false; + } + } + + static boolean ifYesterday(GregorianCalendar date) { + GregorianCalendar yesterday = new GregorianCalendar(); + yesterday.add(Calendar.DAY_OF_MONTH, -1); + + if ((yesterday.get(Calendar.DAY_OF_MONTH) == date.get(Calendar.DAY_OF_MONTH)) && (yesterday.get(Calendar.MONTH) == date.get(Calendar.MONTH)) && (yesterday.get(Calendar.YEAR) == date.get(Calendar.YEAR))) { + return true; + } else { + return false; + } + } + + static String getTweetTime(Long tweetCreatedTime) { + String stringTweetTime = ""; + GregorianCalendar tweetTime = new GregorianCalendar(); + tweetTime.setTime(new Date(tweetCreatedTime)); + Long passedTime = (new Date().getTime() - tweetCreatedTime); + + if(passedTime < TWO_MINUTES) { + stringTweetTime += "только что"; + + } else if(passedTime < HOUR) { + Long minutes = passedTime / MINUTE; + stringTweetTime += minutes.toString() + " минут назад"; + + } else if(ifToday(tweetTime)) { + Long hours = passedTime / HOUR; + stringTweetTime += hours.toString() + " часов назад"; + + } else if(ifYesterday(tweetTime)) { + stringTweetTime += "вчера"; + + } else { + Long days = passedTime / DAY; + stringTweetTime += days.toString() + " дней назад"; + + } + + return stringTweetTime; + } + + + static void printHelp(){ + System.out.println("_________________________________________О ПРОГРАММЕ_________________________________________"); + System.out.println("TwitterStream - консольное приложение, выводящее на экран поток твитов по заданным условиям:"); + System.out.println("\t [--query|-q] - задает ключевое слово, по которому будет осуществляться поиск твитов"); + System.out.println("\t [--stream|-s] - если параметр задан, приложение должно равномерно и непрерывно с задержкой в секунду печатать твиты на экран"); + System.out.println("\t [--hideRetweets] - если параметр задан, нужно фильтровать ретвиты"); + System.out.println("\t [--limit|-l] - вывод только определенного количества твитов, не применимо для --stream режима"); + System.out.println("\t [--help|-h] - печать справки"); + } + + + + //////////////////////////////////////////////////// + static String printTweet(Status status, Boolean ifTime) { + String stringTweet = ""; + + if (ifTime) { + stringTweet += "[" + twitterOutput.getTweetTime(status.getCreatedAt().getTime()) + "] "; + } + + // "\u001B[34m", "\u001B[0m" - цвет ника + stringTweet += "\u001B[34m" + " @" + status.getUser().getScreenName() + ": " + "\u001B[0m"; + + if (status.isRetweet()) { + stringTweet += "ретвитнул " + "\u001B[34m" + " @" + status.getRetweetedStatus().getUser().getScreenName() + ": " + "\u001B[0m"; + } + + stringTweet += status.getText(); + + if (!status.isRetweet() && status.isRetweeted()) { + stringTweet += "(" + status.getRetweetCount() + " ретвитов)"; + } + + return stringTweet; + } + +} diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutputTest.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutputTest.java new file mode 100644 index 0000000..9542063 --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutputTest.java @@ -0,0 +1,223 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +import org.junit.BeforeClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.Assert; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import twitter4j.Status; +import twitter4j.User; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +public class TwitterOutputTest extends Assert { + + private static TwitterOutput twitterOutput; + + private static GregorianCalendar date0; + private static GregorianCalendar date1; + private static GregorianCalendar date2; + private static GregorianCalendar date3; + private static GregorianCalendar date4; + private static GregorianCalendar date5; + private static GregorianCalendar date6; + private static GregorianCalendar date7; + private static GregorianCalendar date8; + private static GregorianCalendar date9; + private static GregorianCalendar date10; + private static GregorianCalendar date11; + private static GregorianCalendar date12; + private static GregorianCalendar date13; + + private static Long time0; + private static Long time1; + private static Long time2; + private static Long time3; + private static Long time4; + + public static final Long SECOND = 1000L; + public static final Long MINUTE = SECOND * 60; + public static final Long HOUR = MINUTE * 60; + public static final Long DAY = HOUR * 24; + + private static Status status1; + private static Status status2; + private static Status status3; + + private static User user1; + private static User user2; + private static User user3; + + + @BeforeClass + public static void setUpCalendarsData() { + + + date0 = new GregorianCalendar(); + + date1 = new GregorianCalendar(); + date1.add(Calendar.DATE, -1); + + date2 = new GregorianCalendar(); + date2.add(Calendar.MONTH, -2); + date2.add(Calendar.YEAR, -2); + + date3 = new GregorianCalendar(); + date3.add(Calendar.DATE, -2); + date3.add(Calendar.YEAR, -2); + + date4 = new GregorianCalendar(); + date4.add(Calendar.DATE, -2); + date4.add(Calendar.MONTH, -2); + + date5 = new GregorianCalendar(); + date5.add(Calendar.YEAR, -2); + + date6 = new GregorianCalendar(); + date6.add(Calendar.MONTH, -2); + + date7 = new GregorianCalendar(); + date7.add(Calendar.DATE, -2); + + date8 = new GregorianCalendar(); + date8.add(Calendar.DATE, -2); + date8.add(Calendar.MONTH, -2); + date8.add(Calendar.YEAR, -2); + + + date9 = new GregorianCalendar();//совпадает только день + date9.add(Calendar.DATE, -1); + date9.add(Calendar.MONTH, -2); + date9.add(Calendar.YEAR, -2); + + date10 = new GregorianCalendar();//совпадает только месяц + date10.add(Calendar.DATE, -1); + date10.add(Calendar.DATE, -2); + date10.add(Calendar.YEAR, -2); + + date11 = new GregorianCalendar();//совпадает только год + date11.add(Calendar.DATE, -2); + date11.add(Calendar.MONTH, -2); + + date12 = new GregorianCalendar();//совпадают день и месяц + date12.add(Calendar.DATE, -1); + date12.add(Calendar.YEAR, -2); + + date13 = new GregorianCalendar();//совпадают день и год + date13.add(Calendar.DATE, -1); + date13.add(Calendar.MONTH, -2); + + time0 = new Date().getTime(); + time1 = new Date().getTime() - MINUTE; + time2 = new Date().getTime() - 30 * MINUTE; + time3 = new Date().getTime() - 2 * HOUR; + time4 = new Date().getTime() - 7 * DAY; + } + + @Test + public void TestingIsToday() { + Assert.assertThat(true, equalTo(twitterOutput.ifToday(date0))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date1))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date2))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date3))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date4))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date5))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date6))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date7))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date8))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date9))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date10))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date11))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date12))); + Assert.assertThat(false, equalTo(twitterOutput.ifToday(date13))); + } + + @Test + public void TestingIsYesterday() { + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date0))); + Assert.assertThat(true, equalTo(twitterOutput.ifYesterday(date1))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date2))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date3))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date4))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date5))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date6))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date7))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date8))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date9))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date10))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date11))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date12))); + Assert.assertThat(false, equalTo(twitterOutput.ifYesterday(date13))); + } + + @Test + public void TestingGetTweetTime() { + Assert.assertThat("Только что", equalTo(twitterOutput.getTweetTime(time0))); + Assert.assertThat("Только что", equalTo(twitterOutput.getTweetTime(time1))); + Assert.assertThat("30 минут назад", equalTo(twitterOutput.getTweetTime(time2))); + date0.roll(Calendar.HOUR, -2); + if (twitterOutput.ifToday(date0)) { + Assert.assertThat("2 часов назад", equalTo(twitterOutput.getTweetTime(time3))); + } else if (twitterOutput.ifYesterday(date0)) { + Assert.assertThat("Вчера", equalTo(twitterOutput.getTweetTime(time3))); + } + Assert.assertThat("7 дней назад", equalTo(twitterOutput.getTweetTime(time4))); + } + /////////////////////////////// + + + @Before + public void SetUpStatuses() { + status1 = mock(Status.class); + user1 = mock(User.class); + when(user1.getScreenName()).thenReturn("John"); + when(status1.getUser()).thenReturn(user1); + when(status1.getCreatedAt()).thenReturn(new Date());//Только что + when(status1.isRetweet()).thenReturn(true);//ретвит + when(status1.getText()).thenReturn("Hello!"); + + + status2 = mock(Status.class); + user2 = mock(User.class); + when(user2.getScreenName()).thenReturn("Mary"); + when(status2.getUser()).thenReturn(user2); + when(status2.getCreatedAt()).thenReturn(new Date());//Только что + when(status2.isRetweet()).thenReturn(false);//не ретвит + when(status2.getText()).thenReturn("Hello!"); + when(status2.isRetweeted()).thenReturn(true); + when(status2.getRetweetCount()).thenReturn(1); + + status3 = mock(Status.class); + user3 = mock(User.class); + when(user3.getScreenName()).thenReturn("Alex"); + when(status3.getUser()).thenReturn(user3); + when(status3.getCreatedAt()).thenReturn(new Date());//Только что + when(status3.isRetweet()).thenReturn(false);//не ретвит + when(status3.getText()).thenReturn("Hello!"); + when(status3.isRetweeted()).thenReturn(false); + + when(status1.getRetweetedStatus()).thenReturn(status3);//ретвитнул @Alex + } + + @Test + public void GetTextToPrintTest() { + Assert.assertThat("[Только что] \u001B[34m@John: \u001B[0mретвитнул \u001B[34m@Alex:" + + " \u001B[0mHello!", equalTo(twitterOutput.printTweet(status1, true))); + Assert.assertThat("[Только что] \u001B[34m@Mary: \u001B[0mHello! (1 ретвитов)", + equalTo(twitterOutput.printTweet(status2, true))); + Assert.assertThat("[Только что] \u001B[34m@Alex: \u001B[0mHello!", + equalTo(twitterOutput.printTweet(status3, true))); + + Assert.assertThat("\u001B[34m@John: \u001B[0mретвитнул \u001B[34m@Alex: \u001B[0mHello!", + equalTo(twitterOutput.printTweet(status1, false))); + Assert.assertThat("\u001B[34m@Mary: \u001B[0mHello! (1 ретвитов)", + equalTo(twitterOutput.printTweet(status2, false))); + Assert.assertThat("\u001B[34m@Alex: \u001B[0mHello!", + equalTo(twitterOutput.printTweet(status3, false))); + } + +} diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java new file mode 100644 index 0000000..ad65ef2 --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java @@ -0,0 +1,81 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import com.beust.jcommander.*; + +public class TwitterParser { + + private JCommander jCommander; + public Boolean checkArgs = false; + + public Boolean isSomethingGoingToPrint = false; + public String printedString = ""; + + private final static int MAX_TWEETS_COUNT = 2700; + + @Parameter(names = { "--query", "-q" }, description = "query or keywords for stream") + private String keyword; + public String getKeyword(){ + return keyword; + } + + @Parameter(names = { "--stream", "-s" }, description = "if stream mode is needed") + private Boolean ifStream = false; + public Boolean getIfStream(){ + return ifStream; + } + + @Parameter(names = { "hideRetweets" }, description = "if it is necessary to hide retweets") + private Boolean hideRetweets = false; + public Boolean getHideRetweets(){ + return hideRetweets; + } + + @Parameter(names = { "--limit", "-l" }, description = "amount of tweets, only for usual mode") + private int limit = -42; + public int getLimit() { + return limit; + } + private Boolean ifLimit = false; + public Boolean getIfLimit() { return ifLimit; } + + @Parameter(names = { "--help", "-h" }, description = "if help is needed") + private Boolean ifHelp = false; + public Boolean getIfHelp() { + return ifHelp; + } + + + + public void ParseArguments(String args[]) throws Exception{ + checkArgs = false; + try { + jCommander = new JCommander(this, args); + if(limit > MAX_TWEETS_COUNT) { + throw new IllegalArgumentException("Limit is out of range"); + } + } catch (Exception exception) { + checkArgs = true; + throw exception; + } + } + + public String printingResultOfSearchingArguments () { + if(getIfStream() && getIfLimit()) { + checkArgs = true; + } + if(checkArgs) { + printedString = "Аргументы переданы неверно\n"; + } + if(checkArgs || getIfHelp()) { + isSomethingGoingToPrint = true; + TwitterOutput.printHelp(); + } + + return printedString; + } + +} diff --git a/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParserTest.java b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParserTest.java new file mode 100644 index 0000000..d7aeb5a --- /dev/null +++ b/TwitterModuleTests/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParserTest.java @@ -0,0 +1,112 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +import com.beust.jcommander.JCommander; +import org.junit.BeforeClass; +import org.junit.Before; +import org.junit.Test; +import org.junit.After; +import org.junit.Assert; + +import static org.hamcrest.CoreMatchers.equalTo; + + +public class TwitterParserTest { + + private static String[] arguments1; + private static String[] arguments2; + private static String[] arguments3; + private static String[] arguments4; + private static TwitterParser twitterParserArgs1; + private static TwitterParser twitterParserArgs2; + private static TwitterParser twitterParserArgs3; + private static TwitterOutput twitterOutput; + private static String printedString; + + @BeforeClass + public static void SetUpArguments() { + arguments1 = new String[]{"-q", "hello", "-s", "-l", "10", "-h"}; + arguments2 = new String[]{"--query", "hello", "--stream", "--hideRetweets", "--limit", "10", "--help"}; + arguments3 = new String[]{}; + arguments4 = new String[]{"-l", "100000000"}; + + twitterParserArgs1 = new TwitterParser(); + twitterParserArgs2 = new TwitterParser(); + twitterParserArgs3 = new TwitterParser(); + } + + @Test + public void GettersTest() { + + JCommander jc1 = new JCommander(twitterParserArgs1, arguments1); + + Assert.assertThat("hello", equalTo(twitterParserArgs1.getKeyword())); + Assert.assertThat(true, equalTo(twitterParserArgs1.getIfStream())); + Assert.assertThat(false, equalTo(twitterParserArgs1.getHideRetweets())); + Assert.assertThat(10, equalTo(twitterParserArgs1.getLimit())); + Assert.assertThat(true, equalTo(twitterParserArgs1.getIfHelp())); + Assert.assertThat(true, equalTo(twitterParserArgs1.getIfLimit())); + + + JCommander jc2 = new JCommander(twitterParserArgs2, arguments2); + + Assert.assertThat("hello", equalTo(twitterParserArgs2.getKeyword())); + Assert.assertThat(true, equalTo(twitterParserArgs2.getIfStream())); + Assert.assertThat(true, equalTo(twitterParserArgs2.getHideRetweets())); + Assert.assertThat(10, equalTo(twitterParserArgs2.getLimit())); + Assert.assertThat(true, equalTo(twitterParserArgs2.getIfHelp())); + Assert.assertThat(true, equalTo(twitterParserArgs2.getIfLimit())); + + + JCommander jc3 = new JCommander(twitterParserArgs3, arguments3); + + Assert.assertThat(false, equalTo(twitterParserArgs3.getIfStream())); + Assert.assertThat(false, equalTo(twitterParserArgs3.getHideRetweets())); + Assert.assertThat(false, equalTo(twitterParserArgs3.getIfHelp())); + Assert.assertThat(false, equalTo(twitterParserArgs3.getIfLimit())); + } + + + @Test + public void PrintingResultOfSearchingArgumentsTest() { + printedString = twitterParserArgs1.printingResultOfSearchingArguments(); + Assert.assertThat(true, equalTo(twitterParserArgs1.checkArgs)); + Assert.assertThat(true, equalTo(printedString.contains("неверно"))); + Assert.assertThat(true, equalTo(printedString.contains("О ПРОГРАММЕ"))); + + printedString = twitterParserArgs3.printingResultOfSearchingArguments(); + Assert.assertThat(false, equalTo(twitterParserArgs3.checkArgs)); + Assert.assertThat(false, equalTo(printedString.contains("О ПРОГРАММЕ"))); + } + + @Test + public void ParseArgumentsTest() throws Exception{ + try { + twitterParserArgs1.ParseArguments(arguments1); + Assert.assertThat(false, equalTo(twitterParserArgs1.checkArgs)); + twitterParserArgs1.ParseArguments(arguments4); + } + catch (Exception e) { + Assert.assertThat("Limit is out of range", equalTo(e.getMessage())); + } + } + + @Before + public void SetUpDataToPrintHelpTest() { + twitterOutput.printHelp(); + } + + @After + public void CleanDataAfterPrintHelpTest() { + twitterParserArgs1.printedString = ""; + twitterParserArgs1.isSomethingGoingToPrint = false; + } + + @Test + public void PrintHelpTest() { + Assert.assertThat(true, equalTo(twitterParserArgs1.isSomethingGoingToPrint)); + Assert.assertThat(true, equalTo(twitterParserArgs1.printedString.contains("О ПРОГРАММЕ"))); + Assert.assertThat(false, equalTo(twitterParserArgs1.isSomethingGoingToPrint)); + Assert.assertThat(false, equalTo(twitterParserArgs1.printedString.contains("О ПРОГРАММЕ"))); + } + +} diff --git a/TwitterS/pom.xml b/TwitterS/pom.xml new file mode 100644 index 0000000..38f2f81 --- /dev/null +++ b/TwitterS/pom.xml @@ -0,0 +1,87 @@ + + + +4.0.0 +ru.fizteh.fivt.students.bulgakova.TwitterStream +TwitterS +jar +1.0-SNAPSHOT +TwitterFirst +http://maven.apache.org + + + junit + junit + 3.8.1 + test + + + + org.twitter4j + twitter4j-stream + 4.0.4 + + + + com.beust + jcommander + 1.48 + + + + + twitter + + + src/main/resources + + + + + org.apache.maven.plugins + maven-compiler-plugin + 2.3.2 + + 1.8 + 1.8 + + + + org.apache.maven.plugins + maven-jar-plugin + 2.3.1 + + + + true + ru.fizteh.fivt.students.bulgakova.TwitterStream.TwitterMain + ru.fizteh.fivt.students.bulgakova.TwitterStream + true + lib/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.4 + + + copy-dependencies + package + + copy-dependencies + + + compile + ${project.build.directory}/lib + + + + + + + diff --git a/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java new file mode 100644 index 0000000..6dabe3a --- /dev/null +++ b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterMain.java @@ -0,0 +1,102 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import twitter4j.*; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +public class TwitterMain { + + private static Twitter twitter; + private static TwitterParser twitterParser; + private static TwitterOutput twitterOutput; + + private static Query query; + private static QueryResult queryResult; + private static BlockingQueue streamQueue; + + private static final int QUEUE_MAX_SIZE = 1000; + private static final int SLEEP_TIME = 1000; + + + public static void main(String[] args) throws Exception { + try { + twitterParser = new TwitterParser(args); + twitterOutput = new TwitterOutput(); + + if (twitterParser.getIfStream()) { + streamMode(); + } else { + usualMode(); + } + System.exit(0); + } catch (TwitterException twitterException) { + System.err.println("Error: twitter"); + } catch (InterruptedException interruptedException) { + System.err.println("Error: sleeping"); + } + + System.exit(0); + } + + private static StatusListener tweetListener = new StatusAdapter() { + public void onStatus(Status status) { + if (!twitterParser.getHideRetweets() || !status.isRetweet()) { + streamQueue.add(status); + } + } + }; + + private static void usualMode() throws Exception { + + twitter = new TwitterFactory().getInstance(); //Singleton??? + query = new Query(twitterParser.getKeyword()); + queryResult = twitter.search(query); + + for (int i = 0; i < twitterParser.getLimit(); i++) { + for (twitter4j.Status status : queryResult.getTweets()) { + if (!status.isRetweet() || !twitterParser.getHideRetweets()) { + TwitterOutput.printTweet(status, true); + } + + i++; + if (i >= twitterParser.getLimit()) { + break; + } + + if(queryResult.hasNext()) { + queryResult = twitter.search(queryResult.nextQuery()); + } else { + break; + } + } + } + + } + + private static void streamMode() throws Exception { + + TwitterStream twitterStream = new TwitterStreamFactory().getInstance(); + twitterStream.addListener(tweetListener); + streamQueue = new ArrayBlockingQueue(QUEUE_MAX_SIZE); + FilterQuery filterQuery = new FilterQuery(); + + filterQuery.track(new String[]{twitterParser.getKeyword()}); + twitterStream.filter(filterQuery); + + while(true) { + while (!streamQueue.isEmpty()) { + Status status = streamQueue.poll(); + TwitterOutput.printTweet(status, false); + Thread.sleep(SLEEP_TIME); + } + } + + } + +} + + diff --git a/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java new file mode 100644 index 0000000..8e54123 --- /dev/null +++ b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterOutput.java @@ -0,0 +1,105 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import twitter4j.Status; +import java.util.GregorianCalendar; +import java.util.Date; +import java.util.Calendar; + +public class TwitterOutput { + + public static final Long SECOND = 1000L; + public static final Long MINUTE = SECOND * 60; + public static final Long TWO_MINUTES = MINUTE * 2; + public static final Long HOUR = MINUTE * 60; + public static final Long DAY = HOUR * 24; + + static boolean ifToday(GregorianCalendar date) { + GregorianCalendar today = new GregorianCalendar(); + + if ( (today.get(Calendar.DAY_OF_MONTH) == date.get(Calendar.DAY_OF_MONTH)) && (today.get(Calendar.MONTH) == date.get(Calendar.MONTH)) && (today.get(Calendar.YEAR) == date.get(Calendar.YEAR))) { + return true; + } else { + return false; + } + } + + static boolean ifYesterday(GregorianCalendar date) { + GregorianCalendar yesterday = new GregorianCalendar(); + yesterday.add(Calendar.DAY_OF_MONTH, -1); + + if ((yesterday.get(Calendar.DAY_OF_MONTH) == date.get(Calendar.DAY_OF_MONTH)) && (yesterday.get(Calendar.MONTH) == date.get(Calendar.MONTH)) && (yesterday.get(Calendar.YEAR) == date.get(Calendar.YEAR))) { + return true; + } else { + return false; + } + } + + static String getTweetTime(Status status) { + String stringTweetTime = ""; + GregorianCalendar tweetTime = new GregorianCalendar(); + tweetTime.setTime(new Date(status.getCreatedAt().getTime())); + Long passedTime = (new Date().getTime() - status.getCreatedAt().getTime()); + + if(passedTime < TWO_MINUTES) { + stringTweetTime += "только что"; + + } else if(passedTime < HOUR) { + Long minutes = passedTime / MINUTE; + stringTweetTime += minutes.toString() + " минут назад"; + + } else if(ifToday(tweetTime)) { + Long hours = passedTime / HOUR; + stringTweetTime += hours.toString() + " часов назад"; + + } else if(ifYesterday(tweetTime)) { + stringTweetTime += "вчера"; + + } else { + Long days = passedTime / DAY; + stringTweetTime += days.toString() + " дней назад"; + + } + + return stringTweetTime; + } + + + static void printHelp(){ + System.out.println("_________________________________________О ПРОГРАММЕ_________________________________________"); + System.out.println("TwitterStream - консольное приложение, выводящее на экран поток твитов по заданным условиям:"); + System.out.println("\t [--query|-q] - задает ключевое слово, по которому будет осуществляться поиск твитов"); + System.out.println("\t [--stream|-s] - если параметр задан, приложение должно равномерно и непрерывно с задержкой в секунду печатать твиты на экран"); + System.out.println("\t [--hideRetweets] - если параметр задан, нужно фильтровать ретвиты"); + System.out.println("\t [--limit|-l] - вывод только определенного количества твитов, не применимо для --stream режима"); + System.out.println("\t [--help|-h] - печать справки"); + } + + static void printTweet(Status status, Boolean ifTime) { + String stringTweet = ""; + + if (ifTime) { + stringTweet += "[" + getTweetTime(status) + "] "; + } + + // "\u001B[34m", "\u001B[0m" - цвет ника + stringTweet += "\u001B[34m" + " @" + status.getUser().getScreenName() + ": " + "\u001B[0m"; + + if (status.isRetweet()) { + stringTweet += "ретвитнул " + "\u001B[34m" + " @" + status.getRetweetedStatus().getUser().getScreenName() + ": " + "\u001B[0m"; + } + + stringTweet += status.getText(); + + if (!status.isRetweet() && status.isRetweeted()) { + stringTweet += "(" + status.getRetweetCount() + " ретвитов)"; + } + + System.out.println(stringTweet); + + } + +} diff --git a/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java new file mode 100644 index 0000000..ad7ce2b --- /dev/null +++ b/TwitterS/src/main/java/ru.fizteh.fivt.students.bulgakova.TwitterStream/TwitterParser.java @@ -0,0 +1,64 @@ +package ru.fizteh.fivt.students.bulgakova.TwitterStream; + +/** + * Created by Bulgakova Daria, 496. + */ + +import com.beust.jcommander.*; + +public class TwitterParser { + + private JCommander jCommander; + private Boolean checkArgs = false; + + @Parameter(names = { "--query", "-q" }, description = "query or keywords for stream") + private String keyword; + public String getKeyword(){ + return keyword; + } + + @Parameter(names = { "--stream", "-s" }, description = "if stream mode is needed") + private Boolean ifStream = false; + public Boolean getIfStream(){ + return ifStream; + } + + @Parameter(names = { "hideRetweets" }, description = "if it is necessary to hide retweets") + private Boolean hideRetweets = false; + public Boolean getHideRetweets(){ + return hideRetweets; + } + + @Parameter(names = { "--limit", "-l" }, description = "amount of tweets, only for usual mode") + private int limit = -42; + public int getLimit() { + return limit; + } + //потом надо будет проверить, задано ли ограничение + + @Parameter(names = { "--help", "-h" }, description = "if help is needed") + private Boolean ifHelp = false; + public Boolean getIfHelp() { + return ifHelp; + } + + + TwitterParser(String args[]) { + try { + jCommander = new JCommander(this, args); + } catch (com.beust.jcommander.ParameterException exception) { + checkArgs = true; + } + + if((getLimit() > 0) && getIfStream()) { + checkArgs = true; + } + + if (checkArgs || getIfHelp()) { + TwitterOutput.printHelp(); + System.exit(0); + } + + } + +} diff --git a/miniORM/pom.xml b/miniORM/pom.xml new file mode 100644 index 0000000..70e9f82 --- /dev/null +++ b/miniORM/pom.xml @@ -0,0 +1,12 @@ + + + 4.0.0 + + miniORM + miniORM + 1.0-SNAPSHOT + + + \ No newline at end of file diff --git a/miniORM/src/main/java/ru/fizteh/fivt/students/bulgakova/miniORM/DatabaseService.java b/miniORM/src/main/java/ru/fizteh/fivt/students/bulgakova/miniORM/DatabaseService.java new file mode 100644 index 0000000..ad62010 --- /dev/null +++ b/miniORM/src/main/java/ru/fizteh/fivt/students/bulgakova/miniORM/DatabaseService.java @@ -0,0 +1,316 @@ +package ru.fizteh.fivt.students.bulgakova.miniORM; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; +import java.lang.reflect.Field; +import java.sql.*; +import java.util.ArrayList; +import java.util.List; + +import static java.lang.System.exit; +import static java.lang.annotation.ElementType.FIELD; +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; +import static java.util.stream.Collectors.joining; + +public class DatabaseService { + + @Target(TYPE) + @Retention(RUNTIME) + public @interface Table { + String name(); + } + + @Target(FIELD) + @Retention(RUNTIME) + public @interface Column { + String name(); + } + + @Target(FIELD) + @Retention(RUNTIME) + public @interface PrimaryKey { + } + + private Class aClass; + + public DatabaseService(Class ac) { + aClass = ac; + } + + public final void insert(T entity) throws IllegalAccessException { + + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + + List columns = new ArrayList<>(); + List values = new ArrayList<>(); + + for (Field field : fields) { + Column column = field.getAnnotation(Column.class); + if (column != null) { + columns.add(column.name()); + values.add(field.get(entity)); + } + } + + try { + Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2"); + String columnsLine = columns.stream().collect(joining(", ")); + String valuesLine = values.stream() + .map(o -> { + if (o instanceof String) { + return "\'" + o + "'"; + } + return o.toString(); }) + .collect(joining(", ")); + + PreparedStatement statement = connection.prepareStatement( + "INSERT INTO " + table + " (" + columnsLine + ") " + + "VALUES (" + valuesLine + ")"); + int updatedLines = statement.executeUpdate(); + System.out.println("Updated: " + updatedLines); + + } catch (SQLException sqle) { + System.out.println("Exception caught in insert: " + sqle.getMessage()); + } + } + + public final List queryForAll() { + List answers = new ArrayList<>(); + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + List columns = new ArrayList<>(); + + for (Field field : fields) { + Column column = field.getAnnotation(Column.class); + if (column != null) { + columns.add(column.name()); + } + } + + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + PreparedStatement statement = connection.prepareStatement("SELECT * FROM " + table); + ResultSet rs = statement.executeQuery(); + + while (rs.next()) { + T answer = (T) aClass.newInstance(); + for (Field field : fields) { + if (field.getType() == int.class) { + field.set(answer, rs.getInt(field.getName())); + } else { + field.set(answer, rs.getString(field.getName())); + } + } + answers.add(answer); + } + } catch (SQLException sqle) { + System.out.println("SQLException caught in queryForAll: " + sqle.getMessage()); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + if (answers.size() == 0) { + return null; + } + return answers; + } + + public final T queryById(K key) { + + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + Field pk = null; + List columns = new ArrayList<>(); + + for (Field field : fields) { + if (field.isAnnotationPresent(PrimaryKey.class)) { + pk = field; + break; + } + + Column column = field.getAnnotation(Column.class); + if (column != null) { + columns.add(column.name()); + } + } + + String pkFieldName = pk.getName(); + List answers = new ArrayList<>(); + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + String keyToFind = key.toString(); + PreparedStatement preparedStatement = + connection.prepareStatement("SELECT * FROM " + table + " WHERE " + pkFieldName + "= ?"); + preparedStatement.setString(1, keyToFind); + ResultSet rs = preparedStatement.executeQuery(); + while (rs.next()) { + T answer = (T) aClass.newInstance(); + for (Field field : fields) { + if (field.getType() == int.class) { + field.set(answer, rs.getInt(field.getName())); + } else { + field.set(answer, rs.getString(field.getName())); + } + } + answers.add(answer); + } + } catch (SQLException sqle) { + System.out.println("SQLException caught in queryById: " + sqle.getMessage()); + } catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + + assert (answers.size() <= 1); + if (answers.size() == 0) { + return null; + } + return answers.get(0); + } + + public final void update(T entity) { + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + Field pk = null; + List columns = new ArrayList<>(); + String keyStr = new String(); + + for (Field field : fields) { + if (field.isAnnotationPresent(PrimaryKey.class)) { + pk = field; + field.setAccessible(true); + try { + field.setAccessible(true); + keyStr = (String) field.get(entity); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + break; + } + Column column = field.getAnnotation(Column.class); + if (column != null) { + columns.add(column.name()); + } + } + String pkFieldName = pk.getName(); + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + PreparedStatement preparedStatement = + connection.prepareStatement("DELETE FROM " + table + " WHERE " + pkFieldName + " = ?"); + preparedStatement.setString(1, keyStr); + preparedStatement.executeUpdate(); + insert(entity); + } catch (SQLException sqle) { + System.out.println("SQLException caught in update: " + sqle.getMessage()); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + + public final void delete(T entity) { + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + Field pk = null; + List columns = new ArrayList<>(); + Object key = null; + String keyStr = new String(); + + for (Field field : fields) { + if (field.isAnnotationPresent(PrimaryKey.class)) { + pk = field; + field.setAccessible(true); + try { + field.setAccessible(true); + keyStr = (String) field.get(entity); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + break; + } + Column column = field.getAnnotation(Column.class); + if (column != null) { + columns.add(column.name()); + } + } + String pkFieldName = pk.getName(); + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + String keyToFind = keyStr; + PreparedStatement preparedStatement = + connection.prepareStatement("DELETE FROM " + table + " WHERE " + pkFieldName + " = ?"); + preparedStatement.setString(1, keyToFind); + preparedStatement.executeUpdate(); + } catch (SQLException sqle) { + System.out.println("SQLException caught in delete: " + sqle.getMessage()); + } + } + + public final void createTable() { + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + Field[] fields = aClass.getDeclaredFields(); + List columnsWithTypes = new ArrayList<>(); + String typename; + for (Field field : fields) { + Column column = field.getAnnotation(Column.class); + if (column != null) { + Class type = field.getType(); + typename = new String(); + if (type == int.class) { + typename += "int"; + } + if (type == long.class) { + typename += "bigint"; + } + if (type == double.class) { + typename += "real"; + } + if (type == String.class) { + typename += "varchar(255)"; + } + if (typename.length() == 0) { + System.out.println("Unsupported type!"); + exit(1); + } + columnsWithTypes.add(column.name() + " " + typename); + } + } + + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + String columnsLine = columnsWithTypes.stream().collect(joining(", ")); + + PreparedStatement statement = connection.prepareStatement("DROP TABLE IF EXISTS " + table); + + statement.executeUpdate(); + + statement = connection.prepareStatement( + "CREATE TABLE " + table + " (" + columnsLine + "); "); + statement.executeUpdate(); + + } catch (SQLException sqle) { + System.out.println("Exception caught in create: " + sqle.getMessage()); + } + } + + public final void dropTable() { + Table annotation = aClass.getAnnotation(Table.class); + String table = annotation.name(); + + try (Connection connection = DriverManager.getConnection("jdbc:h2:./miniORM2")) { + + PreparedStatement statement = connection.prepareStatement("DROP TABLE IF EXISTS" + table + ";"); + statement.executeUpdate(); + + } catch (SQLException sqle) { + System.out.println("Exception caught in drop: " + sqle.getMessage()); + } + } + +} \ No newline at end of file